原文出处:xixicat
序
本文主要讲Java8的新特性,Java8也是一个重要的版本,在语法层面有更大的改动,支持了lamda表达式,影响堪比Java5的泛型支持。
特性列表
lamda表达式(
重磅
)集合的stream操作
提升HashMaps的性能
Date-Time Package
java.lang and java.util Packages
Concurrency
lamda表达式(重磅
)
方法引用
1 /**
2 * 静态方法引用:ClassName::methodName
3 * 实例上的实例方法引用:instanceReference::methodName
4 * 超类上的实例方法引用:super::methodName
5 * 类型上的实例方法引用:ClassName::methodName
6 * 构造方法引用:Class::new
7 * 数组构造方法引用:TypeName[]::new
8 * Created by patterncat on 2016-02-05.
9 */
10 public class MethodReference {
11
12 @Test
13 public void methodRef(){
14 SampleData.getThreeArtists().stream()
15 .map(Artist::getName)
16 .forEach(System.out::println);
17 }
18
19 @Test
20 public void constructorRef(){
21 ArtistFactory<Artist> af = Artist::new;
22 Artist a = af.create("patterncat","china");
23 System.out.println(a);
24 }
25 }
集合的stream操作
1 /** 2 * 静态方法引用:ClassName::methodName 3 * 实例上的实例方法引用:instanceReference::methodName 4 * 超类上的实例方法引用:super::methodName 5 * 类型上的实例方法引用:ClassName::methodName 6 * 构造方法引用:Class::new 7 * 数组构造方法引用:TypeName[]::new 8 * Created by patterncat on 2016-02-05. 9 */ 10 public class MethodReference { 11 12 @Test 13 public void methodRef(){ 14 SampleData.getThreeArtists().stream() 15 .map(Artist::getName) 16 .forEach(System.out::println); 17 } 18 19 @Test 20 public void constructorRef(){ 21 ArtistFactory<Artist> af = Artist::new; 22 Artist a = af.create("patterncat","china"); 23 System.out.println(a); 24 } 25 }
1 /**
2 * 主要接口
3 * 1,predicate
4 * 2,Unary/BinaryOperator:传入参数和返回值必然是同一种数据类型
5 * 3,Int/Double/LongFunction/BiFunction:函数接口并不要求传入参数和返回值之间的数据类型必须一样
6 * 4,Int/Long/DoubleConsumer/BiConsumer:消费数据
7 * 5,Int/Long/DoubleSupplier:生产数据
8 *
9 * 主要方法:
10 * 1,filter
11 * 2,map
12 * 3,reduce
13 * 4,collect
14 * 5,peek
15 * -Djdk.internal.lambda.dumpProxyClasses
16 * Created by patterncat on 2016-02-05.
17 */
18 public class LamdaDemo {
19
20 int[] arr = {4,12,1,3,5,7,9};
21
22 @Test
23 public void filter(){
24 Arrays.stream(arr).filter((x) -> x%2 !=0).forEach(System.out::println);
25 }
26
27 @Test
28 public void map(){
29 Arrays.stream(arr).map((x) -> x * x).forEach(System.out::println);
30 }
31
32 @Test
33 public void reduce(){
34 Arrays.stream(arr).reduce((x,y) -> x+y).ifPresent(System.out::println);
35 System.out.println(Arrays.stream(arr).reduce(-10, (x, y) -> x + y));
36 }
37
38 @Test
39 public void collect(){
40 List<Integer> list = Arrays.stream(arr).collect(ArrayList::new,ArrayList::add,ArrayList::addAll);
41 System.out.println(list);
42
43 Set<Integer> set = list.stream().collect(Collectors.toSet());
44 System.out.println(set);
45
46 Map<String,Artist> map = SampleData.getThreeArtists().stream()
47 .collect(Collectors.toMap(a -> a.getName(),a -> a));
48 System.out.println(map);
49 }
50
51 @Test
52 public void peek(){
53 long count = Arrays.stream(arr).filter(x -> x > 2).peek(System.out::println).count();
54 System.out.println(count);
55 }
56
57 @Test
58 public void average(){
59 Arrays.stream(arr).average().ifPresent(System.out::println);
60 }
61
62 @Test
63 public void sum(){
64 System.out.println(Arrays.stream(arr).sum());
65 }
66
67 @Test
68 public void max(){
69 Arrays.stream(arr).max().ifPresent(System.out::println);
70 }
71
72 @Test
73 public void min(){
74 Arrays.stream(arr).min().ifPresent(System.out::println);
75 }
76
77 @Test
78 public void sorted(){
79 Comparator<Artist> asc = (x,y) -> x.getName().compareTo(y.getName());
80 SampleData.getThreeArtists().stream().sorted(asc).forEach(System.out::println);
81 SampleData.getThreeArtists().stream().sorted(asc.reversed()).forEach(System.out::println);
82 SampleData.getThreeArtists().stream().sorted(Comparator.comparing(Artist::getName)).forEach(System.out::println);
83 SampleData.getThreeArtists().stream().sorted(Comparator.comparing(Artist::getName).reversed()).forEach(System.out::println);
84
85 SampleData.getThreeArtists().stream().sorted(Comparator.comparing(Artist::getName).thenComparing(Artist::getNationality)).forEach(System.out::println);
86 }
87
88 @Test
89 public void groupBy(){
90 Map<String,List<Artist>> rs = SampleData.getThreeArtists().stream().collect(Collectors.groupingBy(Artist::getNationality));
91 System.out.println(rs);
92 }
93
94 @Test
95 public void join(){
96 String joinedNames = SampleData.getThreeArtists().stream().map(Artist::getName).collect(Collectors.joining(","));
97 System.out.println(joinedNames);
98 joinedNames.chars().mapToObj(c -> (char) Character.toUpperCase(c)).forEach(System.out::println);
99 }
100
101 @Test
102 public void flatMap(){
103 Set<Artist> rs = SampleData.getThreeArtists().stream().flatMap(a -> a.getMembers()).collect(Collectors.toSet());
104 rs.stream().forEach(System.out::println);
105 }
106
107 @Test
108 public void arrStream(){
109 Arrays.stream(arr).forEach(System.out::println);
110 }
111
112 @Test
113 public void then(){
114 // IntConsumer out = System.out::println;
115 // IntConsumer err = System.err::println;
116 IntConsumer out = (x) -> System.out.println("out consume:"+x);
117 IntConsumer err = (x) -> System.err.println("err consume:"+x);
118 // Arrays.stream(arr).forEach(out.andThen(err));
119 Arrays.stream(arr).forEach(err.andThen(out));
120 }
121
122
123 @Test
124 public void foreach(){
125 List<Integer> numbers = Arrays.asList(1,2,3,4,5,6);
126 numbers.forEach(System.out::println);
127 }
128
129 @Test
130 public void visitOuterVar(){
131 final int num = 2;
132 Function<Integer,Integer> fun = (from) -> from * num;
133 System.out.println(fun.apply(3));
134 }
135 }
1 /** 2 * 主要接口 3 * 1,predicate 4 * 2,Unary/BinaryOperator:传入参数和返回值必然是同一种数据类型 5 * 3,Int/Double/LongFunction/BiFunction:函数接口并不要求传入参数和返回值之间的数据类型必须一样 6 * 4,Int/Long/DoubleConsumer/BiConsumer:消费数据 7 * 5,Int/Long/DoubleSupplier:生产数据 8 * 9 * 主要方法: 10 * 1,filter 11 * 2,map 12 * 3,reduce 13 * 4,collect 14 * 5,peek 15 * -Djdk.internal.lambda.dumpProxyClasses 16 * Created by patterncat on 2016-02-05. 17 */ 18 public class LamdaDemo { 19 20 int[] arr = {4,12,1,3,5,7,9}; 21 22 @Test 23 public void filter(){ 24 Arrays.stream(arr).filter((x) -> x%2 !=0).forEach(System.out::println); 25 } 26 27 @Test 28 public void map(){ 29 Arrays.stream(arr).map((x) -> x * x).forEach(System.out::println); 30 } 31 32 @Test 33 public void reduce(){ 34 Arrays.stream(arr).reduce((x,y) -> x+y).ifPresent(System.out::println); 35 System.out.println(Arrays.stream(arr).reduce(-10, (x, y) -> x + y)); 36 } 37 38 @Test 39 public void collect(){ 40 List<Integer> list = Arrays.stream(arr).collect(ArrayList::new,ArrayList::add,ArrayList::addAll); 41 System.out.println(list); 42 43 Set<Integer> set = list.stream().collect(Collectors.toSet()); 44 System.out.println(set); 45 46 Map<String,Artist> map = SampleData.getThreeArtists().stream() 47 .collect(Collectors.toMap(a -> a.getName(),a -> a)); 48 System.out.println(map); 49 } 50 51 @Test 52 public void peek(){ 53 long count = Arrays.stream(arr).filter(x -> x > 2).peek(System.out::println).count(); 54 System.out.println(count); 55 } 56 57 @Test 58 public void average(){ 59 Arrays.stream(arr).average().ifPresent(System.out::println); 60 } 61 62 @Test 63 public void sum(){ 64 System.out.println(Arrays.stream(arr).sum()); 65 } 66 67 @Test 68 public void max(){ 69 Arrays.stream(arr).max().ifPresent(System.out::println); 70 } 71 72 @Test 73 public void min(){ 74 Arrays.stream(arr).min().ifPresent(System.out::println); 75 } 76 77 @Test 78 public void sorted(){ 79 Comparator<Artist> asc = (x,y) -> x.getName().compareTo(y.getName()); 80 SampleData.getThreeArtists().stream().sorted(asc).forEach(System.out::println); 81 SampleData.getThreeArtists().stream().sorted(asc.reversed()).forEach(System.out::println); 82 SampleData.getThreeArtists().stream().sorted(Comparator.comparing(Artist::getName)).forEach(System.out::println); 83 SampleData.getThreeArtists().stream().sorted(Comparator.comparing(Artist::getName).reversed()).forEach(System.out::println); 84 85 SampleData.getThreeArtists().stream().sorted(Comparator.comparing(Artist::getName).thenComparing(Artist::getNationality)).forEach(System.out::println); 86 } 87 88 @Test 89 public void groupBy(){ 90 Map<String,List<Artist>> rs = SampleData.getThreeArtists().stream().collect(Collectors.groupingBy(Artist::getNationality)); 91 System.out.println(rs); 92 } 93 94 @Test 95 public void join(){ 96 String joinedNames = SampleData.getThreeArtists().stream().map(Artist::getName).collect(Collectors.joining(",")); 97 System.out.println(joinedNames); 98 joinedNames.chars().mapToObj(c -> (char) Character.toUpperCase(c)).forEach(System.out::println); 99 } 100 101 @Test 102 public void flatMap(){ 103 Set<Artist> rs = SampleData.getThreeArtists().stream().flatMap(a -> a.getMembers()).collect(Collectors.toSet()); 104 rs.stream().forEach(System.out::println); 105 } 106 107 @Test 108 public void arrStream(){ 109 Arrays.stream(arr).forEach(System.out::println); 110 } 111 112 @Test 113 public void then(){ 114 // IntConsumer out = System.out::println; 115 // IntConsumer err = System.err::println; 116 IntConsumer out = (x) -> System.out.println("out consume:"+x); 117 IntConsumer err = (x) -> System.err.println("err consume:"+x); 118 // Arrays.stream(arr).forEach(out.andThen(err)); 119 Arrays.stream(arr).forEach(err.andThen(out)); 120 } 121 122 123 @Test 124 public void foreach(){ 125 List<Integer> numbers = Arrays.asList(1,2,3,4,5,6); 126 numbers.forEach(System.out::println); 127 } 128 129 @Test 130 public void visitOuterVar(){ 131 final int num = 2; 132 Function<Integer,Integer> fun = (from) -> from * num; 133 System.out.println(fun.apply(3)); 134 } 135 }
提升HashMaps的性能
当hash冲突时,以前都是用链表存储,在java8里头,当节点个数>=TREEIFY_THRESHOLD - 1时,HashMap将采用红黑树存储,这样最坏的情况下即所有的key都Hash冲突,采用链表的话查找时间为O(n),而采用红黑树为O(logn)。
Date-Time Package
Java 8新增了LocalDate和LocalTime接口,一方面把月份和星期都改成了enum防止出错,另一方面把LocalDate和LocalTime变成不可变类型,这样就线程安全了。
1 @Test 2 public void today(){ 3 LocalDate today = LocalDate.now(); 4 System.out.println(today); 5 } 6 7 @Test 8 public void parseString(){ 9 // 严格按照ISO yyyy-MM-dd验证,02写成2都不行,当然也有一个重载方法允许自己定义格式 10 LocalDate date = LocalDate.parse("2016-02-05"); 11 System.out.println(date); 12 } 13 14 @Test 15 public void calculate(){ 16 LocalDate today = LocalDate.now(); 17 LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth()); 18 System.out.println(firstDayOfThisMonth); 19 20 // 取本月第2天: 21 LocalDate secondDayOfThisMonth = today.withDayOfMonth(2); 22 System.out.println(secondDayOfThisMonth); 23 24 // 取本月最后一天,再也不用计算是28,29,30还是31: 25 LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth()); 26 System.out.println(lastDayOfThisMonth); 27 28 // 取下一天: 29 LocalDate nextDay = lastDayOfThisMonth.plusDays(1); 30 System.out.println(nextDay); 31 32 // 取2015年1月第一个周一,这个计算用Calendar要死掉很多脑细胞: 33 LocalDate firstMondayOf2015 = LocalDate.parse("2015-01-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)); 34 System.out.println(firstMondayOf2015); 35 } 36 37 @Test 38 public void getTime(){ 39 LocalTime now = LocalTime.now(); 40 System.out.println(now); 41 } 42 43 @Test 44 public void getTimeWithoutMillis(){ 45 LocalTime now = LocalTime.now().withNano(0); 46 System.out.println(now); 47 } 48 49 @Test 50 public void parseTime(){ 51 LocalTime zero = LocalTime.of(0, 0, 0); // 00:00:00 52 System.out.println(zero); 53 54 LocalTime mid = LocalTime.parse("12:00:00"); // 12:00:00 55 System.out.println(mid); 56 }
java.lang and java.util Packages
比如数组的并行排序
1 public class UtilDemo { 2 3 int[] data = {4,12,1,3,5,7,9}; 4 5 @Test 6 public void parallelSort(){ 7 Arrays.parallelSort(data); 8 System.out.println(Arrays.toString(data)); 9 } 10 11 @Test 12 public void testCollectPrallel() { 13 //[4, 16, 17, 20, 25, 32, 41] 14 Arrays.parallelPrefix(data, Integer::sum); 15 System.out.println(Arrays.toString(data)); 16 } 17 }
比如文件遍历
1 @Test 2 public void list() throws IOException { 3 Files.list(Paths.get(".")).filter(Files::isDirectory).forEach(System.out::println); 4 } 5 6 @Test 7 public void walk() throws IOException { 8 Files.walk(Paths.get("."), FileVisitOption.FOLLOW_LINKS).forEach(System.out::println); 9 }
Concurrency
StampedLock
1 public class BankAccountWithStampedLock { 2 3 private final StampedLock lock = new StampedLock(); 4 private double balance; 5 6 public void deposit(double amount) { 7 long stamp = lock.writeLock(); 8 try { 9 balance = balance + amount; 10 } finally { 11 lock.unlockWrite(stamp); 12 } 13 } 14 15 public double getBalance() { 16 long stamp = lock.readLock(); 17 try { 18 return balance; 19 } finally { 20 lock.unlockRead(stamp); 21 } 22 } 23 }
测试
1 @Test 2 public void bench() throws InterruptedException { 3 BankAccountWithStampedLock account = new BankAccountWithStampedLock(); 4 ExecutorService pool = Executors.newCachedThreadPool(); 5 List<Callable<Double>> callables = IntStream.range(1,5) 6 .mapToObj(x -> (Callable<Double>) () -> { 7 // if (x % 2 == 0) { 8 // return account.getBalance(); 9 // } else { 10 // account.deposit(x); 11 // return 0d; 12 // } 13 account.deposit(x); 14 return 0d; 15 }) 16 .collect(Collectors.toList()); 17 pool.invokeAll(callables).forEach(x -> { 18 try { 19 System.out.println(x.get()); 20 } catch (InterruptedException e) { 21 e.printStackTrace(); 22 } catch (ExecutionException e) { 23 e.printStackTrace(); 24 } 25 }); 26 pool.shutdown(); 27 System.out.println(account.getBalance()); 28 }
ConcurrentHashMap的stream支持