一、JDK1.8

名称:Spider(蜘蛛)

发布日期:2014-03-18

新特性:

1.1、扩展方法【接口的默认方法

  Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 default关键字即可,这个特征又叫做扩展方法.

  在Java中只有单继承,如果要让一个类赋予新的特性,通常是使用接口来实现,在C++中支持多继承,允许一个子类同时具有多个父类的接口与功能,在其他语言中,让一个类同时具有其他的可复用代码的方法叫做mixin。新的Java 8 的这个特新在编译器实现的角度上来说更加接近Scala的trait。 在C#中也有名为扩展方法的概念,允许给已存在的类型扩展方法,和Java 8的这个在语义上有差别。

示例:

  1. interface Formula {
  2. double calculate(int a);
  3. default double sqrt(int a) {
  4. return Math.sqrt(a);
  5. }
  6. }
  7. public class ExtendMethod {
  8. public static void main(String[] args) {
  9. Formula formula = new Formula() {
  10. @Override
  11. public double calculate(int a) {
  12. return sqrt(a * 100);
  13. }
  14. };
  15. System.out.println(formula.calculate(100)); // 100.0
  16. System.out.println(formula.sqrt(16)); // 4.0
  17. }
  18. }

  Formula接口在拥有calculate方法之外同时还定义了sqrt方法,实现了Formula接口的子类只需要实现一个calculate方法,默认方法sqrt将在子类上可以直接使用。

  文中的formula被实现为一个匿名类的实例,该代码非常容易理解,6行代码实现了计算 sqrt(a * 100)。

1.2、Lambda表达式

  “Lambda 表达式”(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。

  在java中使用lambda表达式替换匿名类中的函数,使用“() -> {}”代码块替代了整个匿名类中的某个方法函数。

示例1,从匿名类到lambda表达式

  1、匿名类排序

  1. List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
  2. Collections.sort(names, new Comparator<String>() {
  3. @Override
  4. public int compare(String a, String b) {
  5. return b.compareTo(a);
  6. }
  7. });

  只需要给静态方法 Collections.sort 传入一个List对象以及一个比较器来按指定顺序排列。通常做法都是创建一个匿名的比较器对象然后将其传递给sort方法。

  2、java8后lambda表达式

  1. Collections.sort(names, (String a, String b) -> {
  2. return b.compareTo(a);
  3. });

  3、继续优化,对于单行代码只有一个返回值,可以去掉大括号{}以及return关键字

  1. Collections.sort(names, (String a, String b) -> b.compareTo(a));

  4、参数类型推断,Java编译器可以自动推导出参数类型。

  1. Collections.sort(names, (a, b) -> b.compareTo(a));

示例2、多线程的lambda表达式

  1. // Java 8 传统方式:
  2. new Thread(new Runnable() {
  3. @Override
  4. public void run() {
  5. System.out.println("Java 8 传统方式");
  6. }
  7. }).start();
  8.  
  9. // Java 8 lambda方式:
  10. new Thread(() -> System.out.println("Java 8 lambda方式!") ).start();
  11.  
  12. // Java 8 lambda方式:
  13. Runnable runnable = () -> System.out.println("Java 8 lambda方式!多线程");
  14. new Thread(runnable).start();

示例3、遍历for forEach

  1. // Java 8之前:
  2. List<String> features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
  3. for (String feature : features) {
  4. System.out.println(feature);
  5. }
  6.  
  7. // Java 8之后:
  8. List<String> features2 = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
  9. features2.forEach(n -> System.out.println(n));
  10.  
  11. // 使用Java 8的方法引用更方便,方法引用由::双冒号操作符标示
  12. features2.forEach(System.out::println);

示例4、Lambda在Collections中的用法

  1. List<Integer> myList = new ArrayList<>();
  2. for(int i=0; i<100; i++) myList.add(i);
  3.  
  4. //有序流
  5. Stream<Integer> sequentialStream = myList.stream();
  6.  
  7. //并行流
  8. Stream<Integer> parallelStream = myList.parallelStream();
  9.  
  10. //使用lambda表达式,过滤大于90的数字
  11. Stream<Integer> highNums = parallelStream.filter(p -> p > 90);
  12. //lambdag表达式 forEach循环
  13. highNums.forEach(p -> System.out.println("大于90的数 并行="+p));
  14.  
  15. Stream<Integer> highNumsSeq = sequentialStream.filter(p -> p > 90);
  16. highNumsSeq.forEach(p -> System.out.println("大于90的数 有序="+p));

lambda作用域

1、访问外部局部变量【可以访问 后续不能修改,final型】

  1. int num = 1;//等价于 final int num = 1; 固可读,不可修改,即隐性的具有final的语义
  2. Converter<Integer, String> stringConverter =
  3. (from) -> String.valueOf(from + num);
  4. stringConverter.convert(2); //

2、访问对象内字段与静态变量

和本地变量不同的是,lambda内部对于实例的字段以及静态变量是即可读又可写。该行为和匿名对象是一致的:

  1. class Lambda4 {
  2. static int outerStaticNum;
  3. int outerNum;
  4. void testScopes() {
  5. Converter<Integer, String> stringConverter1 = (from) -> {
  6. outerNum = 23;
  7. return String.valueOf(from);
  8. };
  9.  
  10. Converter<Integer, String> stringConverter2 = (from) -> {
  11. outerStaticNum = 72;
  12. return String.valueOf(from);
  13. };
  14. }
  15. }

3、Lambda表达式中是无法访问到默认方法的

  1. interface Formula {
  2. double calculate(int a);
  3. default double sqrt(int a) {
  4. return Math.sqrt(a);
  5. }
  6. }
  7. public class ExtendMethod {
  8. public static void main(String[] args) {
  9. Formula formula = new Formula() {
  10. @Override
  11. public double calculate(int a) {
  12. return sqrt(a * 100);
  13. }
  14. };
  15.  
  16. //Formula formula2 = (a) -> calculate( a * 100); //报错
  17. //Formula formula2 = (a) -> sqrt( a * 100); //报错
  18.  
  19. System.out.println(formula.calculate(100)); // 100.0
  20. System.out.println(formula.sqrt(16)); // 4.0
  21.  
  22. }
  23. }

1.3、函数式接口 

函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。

函数式接口可以被隐式转换为lambda表达式。

函数式接口可以现有的函数友好地支持 lambda。

1、定义

  包含函数式的设计,接口需带有@FunctionalInterface的注解。它注解在接口层面,且注解的接口要有且仅有一个抽象方法。具体就是说,注解在Inteface上,且interface里只能有一个抽象方法,可以有default方法。因为从语义上来讲,一个函数式接口需要通过一个***逻辑上的***方法表达一个单一函数。单一不是说限制你一个interface里只有一个抽象方法,单是多个方法的其他方法需要是继承自Object的public方法,或者你要想绕过,就自己实现default。函数式接口自己本身一定是只有一个抽象方法。同时,如果是Object类的public方法,也是不允许的。

示例查看定义:

  1. // 错误:no target method found
  2. @FunctionalInterface
  3. public interface Func{
  4. }
  5.  
  6. // 正确
  7. @FunctionalInterface
  8. public interface Func1{
  9. void run();
  10. }
  11.  
  12. // 错误:含有多个抽象方法
  13. @FunctionalInterface
  14. public interface Func2{
  15. void run();
  16. void foo();
  17. }
  18.  
  19. // 错误:no target method found,equals 方法签名是Object类的public方法
  20. @FunctionalInterface
  21. public interface Func3{
  22. boolean equals(Object obj);
  23. }
  24.  
  25. // 正确
  26. @FunctionalInterface
  27. public interface Func4{
  28. boolean equals(Object obj);
  29. void run();
  30. }
  31. // 错误:可以是Object的public方法,而clone是protected的,这里相当于有两个抽象方法
  32. @FunctionalInterface
  33. public interface Func5{
  34. Object clone();
  35. void run();
  36. }

2、系统函数式接口

JDK 1.8之前已有的函数式接口:

  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.security.PrivilegedAction
  • java.util.Comparator
  • java.io.FileFilter
  • java.nio.file.PathMatcher
  • java.lang.reflect.InvocationHandler
  • java.beans.PropertyChangeListener
  • java.awt.event.ActionListener
  • javax.swing.event.ChangeListener

JDK 1.8 新增加的函数接口:

  • java.util.function

java.util.function 它包含了很多类,用来支持 Java的 函数式编程,该包中的函数式接口有:

  1. 序号 接口 & 描述
  2. 1 BiConsumer<T,U>
  3. 代表了一个接受两个输入参数的操作,并且不返回任何结果
  4.  
  5. 2 BiFunction<T,U,R>
  6. 代表了一个接受两个输入参数的方法,并且返回一个结果
  7.  
  8. 3 BinaryOperator<T>
  9. 代表了一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果
  10.  
  11. 4 BiPredicate<T,U>
  12. 代表了一个两个参数的boolean值方法
  13.  
  14. 5 BooleanSupplier
  15. 代表了boolean值结果的提供方
  16.  
  17. 6 Consumer<T>
  18. 代表了接受一个输入参数并且无返回的操作
  19.  
  20. 7 DoubleBinaryOperator
  21. 代表了作用于两个double值操作符的操作,并且返回了一个double值的结果。
  22.  
  23. 8 DoubleConsumer
  24. 代表一个接受double值参数的操作,并且不返回结果。
  25.  
  26. 9 DoubleFunction<R>
  27. 代表接受一个double值参数的方法,并且返回结果
  28.  
  29. 10 DoublePredicate
  30. 代表一个拥有double值参数的boolean值方法
  31.  
  32. 11 DoubleSupplier
  33. 代表一个double值结构的提供方
  34.  
  35. 12 DoubleToIntFunction
  36. 接受一个double类型输入,返回一个int类型结果。
  37.  
  38. 13 DoubleToLongFunction
  39. 接受一个double类型输入,返回一个long类型结果
  40.  
  41. 14 DoubleUnaryOperator
  42. 接受一个参数同为类型double,返回值类型也为double
  43.  
  44. 15 Function<T,R>
  45. 接受一个输入参数,返回一个结果。
  46.  
  47. 16 IntBinaryOperator
  48. 接受两个参数同为类型int,返回值类型也为int
  49.  
  50. 17 IntConsumer
  51. 接受一个int类型的输入参数,无返回值
  52.  
  53. 18 IntFunction<R>
  54. 接受一个int类型输入参数,返回一个结果
  55.  
  56. 19 IntPredicate
  57. :接受一个int输入参数,返回一个布尔值的结果。
  58.  
  59. 20 IntSupplier
  60. 无参数,返回一个int类型结果。
  61.  
  62. 21 IntToDoubleFunction
  63. 接受一个int类型输入,返回一个double类型结果
  64.  
  65. 22 IntToLongFunction
  66. 接受一个int类型输入,返回一个long类型结果。
  67.  
  68. 23 IntUnaryOperator
  69. 接受一个参数同为类型int,返回值类型也为int
  70.  
  71. 24 LongBinaryOperator
  72. 接受两个参数同为类型long,返回值类型也为long
  73.  
  74. 25 LongConsumer
  75. 接受一个long类型的输入参数,无返回值。
  76.  
  77. 26 LongFunction<R>
  78. 接受一个long类型输入参数,返回一个结果。
  79.  
  80. 27 LongPredicate
  81. R接受一个long输入参数,返回一个布尔值类型结果。
  82.  
  83. 28 LongSupplier
  84. 无参数,返回一个结果long类型的值。
  85.  
  86. 29 LongToDoubleFunction
  87. 接受一个long类型输入,返回一个double类型结果。
  88.  
  89. 30 LongToIntFunction
  90. 接受一个long类型输入,返回一个int类型结果。
  91.  
  92. 31 LongUnaryOperator
  93. 接受一个参数同为类型long,返回值类型也为long
  94.  
  95. 32 ObjDoubleConsumer<T>
  96. 接受一个object类型和一个double类型的输入参数,无返回值。
  97.  
  98. 33 ObjIntConsumer<T>
  99. 接受一个object类型和一个int类型的输入参数,无返回值。
  100.  
  101. 34 ObjLongConsumer<T>
  102. 接受一个object类型和一个long类型的输入参数,无返回值。
  103.  
  104. 35 Predicate<T>
  105. 接受一个输入参数,返回一个布尔值结果。
  106.  
  107. 36 Supplier<T>
  108. 无参数,返回一个结果。
  109.  
  110. 37 ToDoubleBiFunction<T,U>
  111. 接受两个输入参数,返回一个double类型结果
  112.  
  113. 38 ToDoubleFunction<T>
  114. 接受一个输入参数,返回一个double类型结果
  115.  
  116. 39 ToIntBiFunction<T,U>
  117. 接受两个输入参数,返回一个int类型结果。
  118.  
  119. 40 ToIntFunction<T>
  120. 接受一个输入参数,返回一个int类型结果。
  121.  
  122. 41 ToLongBiFunction<T,U>
  123. 接受两个输入参数,返回一个long类型结果。
  124.  
  125. 42 ToLongFunction<T>
  126. 接受一个输入参数,返回一个long类型结果。
  127.  
  128. 43 UnaryOperator<T>
  129. 接受一个参数为类型T,返回值类型也为T

3、常用函数式接口使用

1️⃣、Function<T, R> 功能型函数式接口

T:入参类型,R:出参类型

调用方法:R apply(T t);

定义函数示例:Function<Integer, Integer> func = p -> p * 10;    // 输出入参的10倍

调用函数示例:func.apply(10);    // 结果100

接口定义说明:

  1. package java.util.function;
  2. import java.util.Objects;
  3.  
  4. @FunctionalInterface
  5. public interface Function<T, R> {
  6. // 将参数赋予给相应方法
  7. R apply(T t);
  8.  
  9. // 先执行参数(即也是一个Function)的,再执行调用者(同样是一个Function)
  10. default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
  11. Objects.requireNonNull(before);
  12. return (V v) -> apply(before.apply(v));
  13. }
  14.  
  15. // 先执行调用者,再执行参数,和compose相反。
  16. default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
  17. Objects.requireNonNull(after);
  18. return (T t) -> after.apply(apply(t));
  19. }
  20.  
  21. // 返回当前正在执行的方法
  22. static <T> Function<T, T> identity() {
  23. return t -> t;
  24. }
  25. }

示例

  1. Function<Integer, Integer> times2 = i -> i*2;
  2. Function<Integer, Integer> squared = i -> i*i;
  3.  
  4. System.out.println(times2.apply(4));
  5. System.out.println(squared.apply(4));
  6.  
  7. //先4×4然后16×2,先执行apply(4),在times2的apply(16),先执行参数,再执行调用者。
  8. System.out.println(times2.compose(squared).apply(4)); //32
  9.  
  10. // 先4×2,然后8×8,先执行times2的函数,在执行squared的函数。
  11. System.out.println(times2.andThen(squared).apply(4)); //64
  12.  
  13. // 取出 Function.identity().compose(squared) 的 squared执行,结果 4x4
  14. System.out.println(Function.identity().compose(squared).apply(4)); //16
  15. // 取出 Function.identity().apply(4) 的 4执行,结果 4
  16. System.out.println(Function.identity().apply(4)); //

理解:Function类,是一个方法,类似c++里面函数指针,一个变量可以指向一个方法,并且可以把两个方法组合起来使用(使用compose和andThen),而可以通过identity这个静态方法来获取当前执行的方法。

2️⃣、Predicate<T>断言型函数式接口

T:入参类型;出参类型是Boolean

调用方法:boolean test(T t);

定义函数示例:Predicate<Integer> predicate = p -> p % 2 == 0;    // 判断是否、是不是偶数

调用函数示例:predicate.test(100);    // 运行结果true

接口定义说明

  1. package java.util.function;
  2. import java.util.Objects;
  3.  
  4. // 一个谓词,布尔类型函数
  5. @FunctionalInterface
  6. public interface Predicate<T> {
  7.  
  8. // 根据给定参数 获取布尔值
  9. boolean test(T t);
  10.  
  11. // and 与 &&
  12. default Predicate<T> and(Predicate<? super T> other) {
  13. Objects.requireNonNull(other);
  14. return (t) -> test(t) && other.test(t);
  15. }
  16.  
  17. // 取反
  18. default Predicate<T> negate() {
  19. return (t) -> !test(t);
  20. }
  21.  
  22. // or 或者
  23. default Predicate<T> or(Predicate<? super T> other) {
  24. Objects.requireNonNull(other);
  25. return (t) -> test(t) || other.test(t);
  26. }
  27.  
  28. // 相等
  29. static <T> Predicate<T> isEqual(Object targetRef) {
  30. return (null == targetRef)
  31. ? Objects::isNull
  32. : object -> targetRef.equals(object);
  33. }
  34. }

示例

  1. String tempStr="Spring is A";
  2. Predicate<String> length5=p->p.length()>=5;
  3. Predicate<String> containA=p->p.contains("A");
  4. Predicate<String> containB=p->p.contains("B");
  5. // 长度大于5 true
  6. System.out.println(length5.test(tempStr));
  7. // 包含A true
  8. System.out.println(containA.test(tempStr));
  9.  
  10. // 长度大于5 and 包含A true
  11. System.out.println(length5.and(containA).test(tempStr));
  12. // 长度大于5 and 包含B false
  13. System.out.println(length5.and(containB).test(tempStr));
  14. // 长度大于5 or 包含B false
  15. System.out.println(length5.or(containB).test(tempStr));
  16. // 长度大于5 取反 false
  17. System.out.println(length5.negate().test(tempStr));
  18. // 长度大于5 取反 false
  19. System.out.println(!length5.test(tempStr));

3️⃣、Supplier<T>供给型函数式接口

T:出参类型;没有入参

调用方法:T get();

定义函数示例:Supplier<Integer> supplier= () -> 100;    // 常用于业务“有条件运行”时,符合条件再调用获取结果的应用场景;运行结果须提前定义,但不运行。

调用函数示例:supplier.get();

接口定义说明:

  1. package java.util.function;
  2.  
  3. // 生产型
  4. @FunctionalInterface
  5. public interface Supplier<T> {
  6.  
  7. //得到一个结果
  8. T get();
  9. }

示例

  1. public static String supplierTest(Supplier<String> supplier) {
  2. return supplier.get();
  3. }
  4. public static void main(String[] args) {
  5. String name = "测试";
  6. // () -> name.length() 无参数,返回一个结果(字符串长度)
  7. // 所以该lambda表达式可以实现Supplier接口
  8. System.out.println(supplierTest(() -> name.length() + ""));
  9. }

4️⃣、Consumer<T>消费型

T:入参类型;没有出参

调用方法:void accept(T t);

定义函数示例:Consumer<String> consumer= p -> System.out.println(p);    // 因为没有出参,常用于打印、发送短信等消费动作

调用函数示例:consumer.accept("18800008888");

接口方法定义

  1. package java.util.function;
  2. import java.util.Objects;
  3.  
  4. @FunctionalInterface
  5. public interface Consumer<T> {
  6.  
  7. void accept(T t);
  8.  
  9. default Consumer<T> andThen(Consumer<? super T> after) {
  10. Objects.requireNonNull(after);
  11. return (T t) -> { accept(t); after.accept(t); };
  12. }
  13. }

示例

  1. public static void modifyTheValue3(int value, Consumer<Integer> consumer) {
  2. consumer.accept(value);
  3. }
  4.  
  5. public static void main(String[] args) {
  6. // (x) -> System.out.println(x * 2)接受一个输入参数x
  7. // 直接输出,并没有返回结果
  8. // 所以该lambda表达式可以实现Consumer接口
  9. modifyTheValue3(3, (x) -> System.out.println(x * 2));
  10. }

1.4、方法引用和构造引用

  方法引用是对Lambda表达式符合某种情况下的一种缩写,使得我们的Lambda表达式更加的精简, 也可以理解为Lambda表达式的另一种表现形式(缩写)

  使用 :: 关键字来传递方法或者构造函数引用

方法引用

1、静态引用【指向静态方法的方法引用】类名::静态方法名

  1. @FunctionalInterface
  2. interface Converter<F, T> {
  3. T convert(F from);
  4. }
  5. public class TestReference {
  6. public static void main(String[] args) {
  7. //静态引用
  8. Converter<String, Integer> converter = Integer::valueOf;
  9. Integer converted = converter.convert("123");
  10. System.out.println(converted); //
  11. }
  12. }

2、指向任意类型实例方法的方法引用(这个实例为方法的参数)【类名::实例方法名】

  1. //指向任意类型实例方法的方法引用(这个实例为方法的参数)
  2. List<String> list = Arrays.asList("av","asdf","sad","324","43");
  3. List<String> collect = list.stream().map(String::toUpperCase).collect(Collectors.toList());
  4. System.out.println(collect);

3、向现有对象的实例方法的方法引用(这个实例为外部对象)【实例对象名::实例方法名】

  1. //指向现有对象的实例方法的方法引用(这个实例为外部对象)
  2. List<String> list2 = Arrays.asList("av","asdf","sad","324","43");
  3. String a="avasdf";
  4. List<String> collect2 = list2.stream().filter(a::contains).collect(Collectors.toList());
  5. System.out.println(collect2);

典型示例

  1. //传统Lambda表达式
  2. Consumer<String> consumer = (x) -> System.out.println(x);
  3. consumer.accept("Hi: 我是Lambda表达式实现的!");
  4. //方法引用实现
  5. consumer = System.out::println;
  6. consumer.accept("Hello : 我是使用方法引用实现的 ");

4、构造引用【类名 :: new 】

  与函数式接口相结合,自动与函数式接口中方法兼容。 可以把构造器引用赋值给定义的方法。

  1. //传统Lambda方式
  2. Supplier<Map> mapSupplier = ()-> new HashMap<String,String>();
  3. Map map = mapSupplier.get();
  4. System.out.println(map);
  5.  
  6. //构造器引用
  7. mapSupplier = HashMap::new;
  8. map = mapSupplier.get();
  9. System.out.println(map);

009-jdk1.8版本新特性一-展方法,Lambda表达式,函数式接口、方法引用构造引用的更多相关文章

  1. Java8新特性学习笔记(一) Lambda表达式

    没有用Lambda表达式的写法: Comparator<Transaction> byYear = new Comparator<Transaction>() { @Overr ...

  2. Java8新特性第1章(Lambda表达式)

    在介绍Lambda表达式之前,我们先来看只有单个方法的Interface(通常我们称之为回调接口): public interface OnClickListener { void onClick(V ...

  3. Java8新特性(一)——Lambda表达式与函数式接口

    一.Java8新特性概述 1.Lambda 表达式 2. 函数式接口 3. 方法引用与构造器引用 4. Stream API 5. 接口中的默认方法与静态方法 6. 新时间日期 API 7. 其他新特 ...

  4. 【Java8新特性】还没搞懂函数式接口?赶快过来看看吧!

    写在前面 Java8中内置了一些在开发中常用的函数式接口,极大的提高了我们的开发效率.那么,问题来了,你知道都有哪些函数式接口吗? 函数式接口总览 这里,我使用表格的形式来简单说明下Java8中提供的 ...

  5. jdk8新特性-亮瞎眼的lambda表达式

    jdk8之前,尤其是在写GUI程序的事件监听的时候,各种的匿名内部类,大把大把拖沓的代码,程序毫无美感可言!既然Java中一切皆为对象,那么,就类似于某些动态语言一样,函数也可以当成是对象啊!代码块也 ...

  6. Java 8 新特性-菜鸟教程 (3) -Java 8 函数式接口

    Java 8 函数式接口 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口. 函数式接口可以被隐式转换为lambda表达式. 函数式接 ...

  7. Java8新特性(三)——Optional类、接口方法与新时间日期API

    一.Optional容器类 这是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. 查看结构图可以看到有如下常用方法: of(T)—— ...

  8. Java8新特性 -- 四大内置的核心函数式接口

    可以把这些函数式接口作为方法的参数. 1.0 核心内置函数式接口一: 消费型接口@FunctionalInterfacepublic interface Consumer<T> { voi ...

  9. Java8新特性 利用流和Lambda表达式对List集合进行处理

    Lambda表达式处理List 最近在做项目的过程中经常会接触到 lambda 表达式,随后发现它基本上可以替代所有 for 循环,包括增强for循环.也就是我认为,绝大部分的for循环都可以用 la ...

随机推荐

  1. 设置ADB网络连接目标板

    adb connect 网络连接目标板报错,原因参考[http://ytydyd.blog.sohu.com/146260552.html].而且指定 adb connect <IP>:5 ...

  2. hadoop完全分布式搭建HA(高可用)

    2018年03月25日 16:25:26 D调的Stanley 阅读数:2725 标签: hadoop HAssh免密登录hdfs HA配置hadoop完全分布式搭建zookeeper 配置 更多 个 ...

  3. 【Python学习】记一次开源博客系统Blog_mini源码学习历程-Flask

    今天准备看看Flask框架,找到一套博客系统源码,拿来学习学习 https://github.com/xpleaf/Blog_mini 演示地址 http://140.143.205.19 技术框架 ...

  4. pace.js简介

    Pace.js – 超赞的页面加载进度自动指示和 Ajax 导航效果 在页面中引入 Pace.js 和您所选择主题的 CSS 文件,就可以让你的页面拥有漂亮的加载进度和 Ajax 导航效果.不需要挂接 ...

  5. Android studio快捷键设置

    Android Studio格式化代码设置和代码风格设置.代码提示键  http://blog.csdn.net/u010156024/article/details/48207145 Android ...

  6. openvpn 负载均衡方案

    这些方案的前提是,vpnserver的key都是一样的.方案1在openvpn客户端设两个配置文件,我们自己手动去连接去选择方案2在openvpn 的配置文件里面加个随机参数remote 8.8.8. ...

  7. php 加密压缩

    php 把文件打成压缩包 ,可以去搜下 pclzip 搜很好多地方没有找到对压缩包进行加密操作的. 如果服务器是linux 那么见代码: $filename="test.csv"; ...

  8. FtpWebRequest UploadFile返回"The underlying connection was closed: The server committed a protocol violation."解决方法

    将FtpWebRequest的KeepAlive设置为true. return Return<Boolean>( new Uri(ftpPath + fileName), request ...

  9. 使用Autolayout xib实现动态高度的TableViewCell

    http://my.oschina.net/u/2360693/blog/481236?p={{totalPage}} 创建Xib文件 首先将Cell做好布局,调整到满意的位置和宽度,然后开始做Aut ...

  10. Windows Server 2008 R2之一活动目录服务部署

    测试环境: 服务器:计算机名Win2008R2CNDC,已安装Windows Server 2008 R2.IPV4:192.168.1.13,255.255.255.0,网关地址192.168.1. ...