Java8的新特性

原文出处: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  * 主要接口
  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支持

参考

posted @ 2017-09-26 06:54  流星<。)#)))≦  阅读(304)  评论(0编辑  收藏  举报