本文共 7518 字,大约阅读时间需要 25 分钟。
内容来自《 java8实战 》,本篇文章内容均为非盈利,旨为方便自己查询、总结备份、开源分享。如有侵权请告知,马上删除。
书籍购买地址:
用行为参数化把代码传递给方法
@Testpublic void test() throws Exception { Listints = Arrays.asList(1,3,4,5,1,5,7,7,8); ints.sort(new Comparator () { @Override public int compare(Integer o1, Integer o2) { return o1.compareTo(o2); //升序 } }); System.out.println(ints); ints.sort(new Comparator () { @Override public int compare(Integer o1, Integer o2) { return - o1.compareTo(o2); //降序 } }); System.out.println(ints);}
并行与共享的可变数据
并发是两个任务可以在重叠的时间段内启动,运行和完成。并行是任务在同一时间运行,例如,在多核处理器上。 并发是独立执行过程的组合,而并行是同时执行(可能相关的)计算。 并发是一次处理很多事情,并行是同时做很多事情。 应用程序可以是并发的,但不是并行的,这意味着它可以同时处理多个任务,但是没有两个任务在同一时刻执行。 应用程序可以是并行的,但不是并发的,这意味着它同时处理多核CPU中的任务的多个子任务。 一个应用程序可以即不是并行的,也不是并发的,这意味着它一次一个地处理所有任务。 应用程序可以即是并行的也是并发的,这意味着它同时在多核CPU中同时处理多个任务。
方法引用
@Testpublic void test() throws Exception { File[] files = new File(".").listFiles(new FileFilter() { @Override public boolean accept(File pathname) { return pathname.isHidden(); } }); for (File file : files) { System.out.println(file); }}
pathname.isHidden()
,java8引入之前只能这么写,但是现在可以这样@Testpublic void test() throws Exception { File[] files = new File(".").listFiles((File::isHidden)); for (File file : files) { System.out.println("file = " + file); }}
lambda匿名函数
(int x ) -> x+1
,代码的意思就是你传入一个2,那么他会返回3,也可以像上面定义一个方法add1,然后class::add1,但是对于简短逻辑明确的代码来说这样更简洁,如果匿名函数有很多行代码,不能一眼看出这个匿名函数是干嘛的,那么就应该把匿名函数抽出来一个方法使用实例
@AllArgsConstructor@NoArgsConstructor@Datapublic class Apple { private String color; private Integer weight;}
@Testpublic void test() throws Exception { Listapples = new ArrayList<>(); for (Apple apple : apples) { if ("green".equals(apple.getColor())){ System.out.println(apple); } }}
@Testpublic void test() throws Exception { Listapples = new ArrayList<>(); for (Apple apple : apples) { if (1000 < apple.getWeight()){ //其他代码与上面都是一直的,无奈的是只能复制黏贴改条件,复制黏贴是为限的,因为如果有一天需要改一个地方,如果忘记了另一处复制的代码,那么就会出错 System.out.println(apple); } }}
@AllArgsConstructor@NoArgsConstructor@Datapublic class Apple { private String color; private Integer weight; public static boolean filterWeight(Apple apple){ return 1000 < apple.getWeight(); } public static boolean filterColor(Apple apple){ return "green".equals(apple.getColor()); }}
public interface FindApple{ boolean find(T t);}
@Testpublic void test() throws Exception { Listapples = new ArrayList<>(); filterApple(apples,Apple::filterColor); //java8之后:苹果根据条件过滤:找出绿色苹果 filterApple(apples,Apple::filterWeight); //java8之后:苹果根据条件过滤:找出1000克以上的大苹果}static void filterApple(List apples,FindApple f){ for (Apple apple : apples) { if (f.find(apple)){ System.out.println(apple); } }}
filterApple
中的f.find(apple)
,都是可以看出来这是在使用接口中的测试方法,但是这个方法没有实现自己的逻辑,所以到这它是不能按照要求过滤apple的,然后在上面junit测试方法中,传入的Apple::filterColor
其实就是为接口中的测试方法添加逻辑,使其能按照我们的要求过滤apple从传递方法到lambda
@Testpublic void test() throws Exception { Listapples = new ArrayList<>(); filterApple(apples,(apple -> "green".equals(apple.getColor()))); filterApple(apples,(apple -> (apple.getWeight() > 1000)));}static void filterApple(List apples, Predicate f){ for (Apple apple : apples) { if (f.test(apple)){ System.out.println(apple); } }}
这时候看到的变化是从原来的FindApple接口改变为了Predicate接口,其实这个接口的定义跟刚才的FIndApple接口内定义是一样一样的,如下
@FunctionalInterfacepublic interface Predicate{ boolean test(T t); .... ....}
日常写代码的时候,在java8之前如果要遍历Map中找出map对应key的特定value值,如果更加复杂的类型就需要嵌套循环并且编写出来的代码是一大坨的
void test() throws Exception {
Map maps = new HashMap<>();for (Map.Entry integerStringEntry : maps.entrySet()) {if (integerStringEntry.getKey() > 1000) { if (integerStringEntry.getValue().equals("value")){ System.out.println("integerStringEntry = " + integerStringEntry); }}
}
}Stream api就类似SQL一样的过滤操作,如上的代码可以写为下面这样的
void test() throws Exception {
Map maps = new HashMap<>();maps.entrySet().stream().filter(entry -> entry.getKey() > 1000) .filter(entry -> entry.getValue().equals("value")) .forEach(System.out::println);
}
- 在两个cpu上筛选数据,分割数据到两个cpu上,如1- 按条件过滤数据,如2- 一个cpu会将结果汇总起来,如3
Stream顺序处理
maps.entrySet().stream()....
Stream的并行处理
maps.entrySet().parallelStream()....
默认方法的定义是由default开始的,比如
public interface MyFunction { default boolean test(String str) { return str.equals(".."); }}public class UU implements MyFunction{ public static void main(String[] args) { UU uu = new UU(); System.out.println(uu.test("..")); }}
public class UU implements MyFunction{ @Override public boolean test(String str) { return "ll".equals(str); } public static void main(String[] args) { UU uu = new UU(); System.out.println(uu.test("..")); }}
public interface MyFunction1 { default boolean test(String str) { return str.equals(".."); }}public interface MyFunction2 { default boolean test(String str) { return str.equals("ll"); }}public class UU implements MyFunction1,MyFunction2{ //exception public static void main(String[] args) { UU uu = new UU(); System.out.println(uu.test("..")); }}
这就是为什么在更新为java8之后,之前的代码还是可以使用的原因,java8 在Collection接口中加入了stream默认实现了
default Streamstream() { return StreamSupport.stream(spliterator(), false); }
转载地址:http://owcia.baihongyu.com/