在路上

 找回密码
 立即注册
在路上 站点首页 学习 查看内容

Java8的新特性

2017-3-7 12:53| 发布者: zhangjf| 查看: 1326| 评论: 0

摘要: 来自: https://segmentfault.com/a/1190000004419611 java语言特性系列 Java5的新特性 Java6的新特性 Java7的新特性 Java8的新特性 Java9的新特性 ...

来自: https://segmentfault.com/a/1190000004419611

java语言特性系列

Java5的新特性

Java6的新特性

Java7的新特性

Java8的新特性

Java9的新特性

本文主要讲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. @Test
  12. public void methodRef(){
  13. SampleData.getThreeArtists().stream()
  14. .map(Artist::getName)
  15. .forEach(System.out::println);
  16. }
  17. @Test
  18. public void constructorRef(){
  19. ArtistFactory<Artist> af = Artist::new;
  20. Artist a = af.create("patterncat","china");
  21. System.out.println(a);
  22. }
  23. }
复制代码
集合的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. int[] arr = {4,12,1,3,5,7,9};
  20. @Test
  21. public void filter(){
  22. Arrays.stream(arr).filter((x) -> x%2 !=0).forEach(System.out::println);
  23. }
  24. @Test
  25. public void map(){
  26. Arrays.stream(arr).map((x) -> x * x).forEach(System.out::println);
  27. }
  28. @Test
  29. public void reduce(){
  30. Arrays.stream(arr).reduce((x,y) -> x+y).ifPresent(System.out::println);
  31. System.out.println(Arrays.stream(arr).reduce(-10, (x, y) -> x + y));
  32. }
  33. @Test
  34. public void collect(){
  35. List<Integer> list = Arrays.stream(arr).collect(ArrayList::new,ArrayList::add,ArrayList::addAll);
  36. System.out.println(list);
  37. Set<Integer> set = list.stream().collect(Collectors.toSet());
  38. System.out.println(set);
  39. Map<String,Artist> map = SampleData.getThreeArtists().stream()
  40. .collect(Collectors.toMap(a -> a.getName(),a -> a));
  41. System.out.println(map);
  42. }
  43. @Test
  44. public void peek(){
  45. long count = Arrays.stream(arr).filter(x -> x > 2).peek(System.out::println).count();
  46. System.out.println(count);
  47. }
  48. @Test
  49. public void average(){
  50. Arrays.stream(arr).average().ifPresent(System.out::println);
  51. }
  52. @Test
  53. public void sum(){
  54. System.out.println(Arrays.stream(arr).sum());
  55. }
  56. @Test
  57. public void max(){
  58. Arrays.stream(arr).max().ifPresent(System.out::println);
  59. }
  60. @Test
  61. public void min(){
  62. Arrays.stream(arr).min().ifPresent(System.out::println);
  63. }
  64. @Test
  65. public void sorted(){
  66. Comparator<Artist> asc = (x,y) -> x.getName().compareTo(y.getName());
  67. SampleData.getThreeArtists().stream().sorted(asc).forEach(System.out::println);
  68. SampleData.getThreeArtists().stream().sorted(asc.reversed()).forEach(System.out::println);
  69. SampleData.getThreeArtists().stream().sorted(Comparator.comparing(Artist::getName)).forEach(System.out::println);
  70. SampleData.getThreeArtists().stream().sorted(Comparator.comparing(Artist::getName).reversed()).forEach(System.out::println);
  71. SampleData.getThreeArtists().stream().sorted(Comparator.comparing(Artist::getName).thenComparing(Artist::getNationality)).forEach(System.out::println);
  72. }
  73. @Test
  74. public void groupBy(){
  75. Map<String,List<Artist>> rs = SampleData.getThreeArtists().stream().collect(Collectors.groupingBy(Artist::getNationality));
  76. System.out.println(rs);
  77. }
  78. @Test
  79. public void join(){
  80. String joinedNames = SampleData.getThreeArtists().stream().map(Artist::getName).collect(Collectors.joining(","));
  81. System.out.println(joinedNames);
  82. joinedNames.chars().mapToObj(c -> (char) Character.toUpperCase(c)).forEach(System.out::println);
  83. }
  84. @Test
  85. public void flatMap(){
  86. Set<Artist> rs = SampleData.getThreeArtists().stream().flatMap(a -> a.getMembers()).collect(Collectors.toSet());
  87. rs.stream().forEach(System.out::println);
  88. }
  89. @Test
  90. public void arrStream(){
  91. Arrays.stream(arr).forEach(System.out::println);
  92. }
  93. @Test
  94. public void then(){
  95. // IntConsumer out = System.out::println;
  96. // IntConsumer err = System.err::println;
  97. IntConsumer out = (x) -> System.out.println("out consume:"+x);
  98. IntConsumer err = (x) -> System.err.println("err consume:"+x);
  99. // Arrays.stream(arr).forEach(out.andThen(err));
  100. Arrays.stream(arr).forEach(err.andThen(out));
  101. }
  102. @Test
  103. public void foreach(){
  104. List<Integer> numbers = Arrays.asList(1,2,3,4,5,6);
  105. numbers.forEach(System.out::println);
  106. }
  107. @Test
  108. public void visitOuterVar(){
  109. final int num = 2;
  110. Function<Integer,Integer> fun = (from) -> from * num;
  111. System.out.println(fun.apply(3));
  112. }
  113. }
复制代码
提升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. @Test
  7. public void parseString(){
  8. // 严格按照ISO yyyy-MM-dd验证,02写成2都不行,当然也有一个重载方法允许自己定义格式
  9. LocalDate date = LocalDate.parse("2016-02-05");
  10. System.out.println(date);
  11. }
  12. @Test
  13. public void calculate(){
  14. LocalDate today = LocalDate.now();
  15. LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth());
  16. System.out.println(firstDayOfThisMonth);
  17. // 取本月第2天:
  18. LocalDate secondDayOfThisMonth = today.withDayOfMonth(2);
  19. System.out.println(secondDayOfThisMonth);
  20. // 取本月最后一天,再也不用计算是28,29,30还是31:
  21. LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth());
  22. System.out.println(lastDayOfThisMonth);
  23. // 取下一天:
  24. LocalDate nextDay = lastDayOfThisMonth.plusDays(1);
  25. System.out.println(nextDay);
  26. // 取2015年1月第一个周一,这个计算用Calendar要死掉很多脑细胞:
  27. LocalDate firstMondayOf2015 = LocalDate.parse("2015-01-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
  28. System.out.println(firstMondayOf2015);
  29. }
  30. @Test
  31. public void getTime(){
  32. LocalTime now = LocalTime.now();
  33. System.out.println(now);
  34. }
  35. @Test
  36. public void getTimeWithoutMillis(){
  37. LocalTime now = LocalTime.now().withNano(0);
  38. System.out.println(now);
  39. }
  40. @Test
  41. public void parseTime(){
  42. LocalTime zero = LocalTime.of(0, 0, 0); // 00:00:00
  43. System.out.println(zero);
  44. LocalTime mid = LocalTime.parse("12:00:00"); // 12:00:00
  45. System.out.println(mid);
  46. }
复制代码
java.lang and java.util Packages

比如数组的并行排序

  1. public class UtilDemo {
  2. int[] data = {4,12,1,3,5,7,9};
  3. @Test
  4. public void parallelSort(){
  5. Arrays.parallelSort(data);
  6. System.out.println(Arrays.toString(data));
  7. }
  8. @Test
  9. public void testCollectPrallel() {
  10. //[4, 16, 17, 20, 25, 32, 41]
  11. Arrays.parallelPrefix(data, Integer::sum);
  12. System.out.println(Arrays.toString(data));
  13. }
  14. }
复制代码

比如文件遍历

  1. @Test
  2. public void list() throws IOException {
  3. Files.list(Paths.get(".")).filter(Files::isDirectory).forEach(System.out::println);
  4. }
  5. @Test
  6. public void walk() throws IOException {
  7. Files.walk(Paths.get("."), FileVisitOption.FOLLOW_LINKS).forEach(System.out::println);
  8. }
复制代码
Concurrency

StampedLock

  1. public class BankAccountWithStampedLock {
  2. private final StampedLock lock = new StampedLock();
  3. private double balance;
  4. public void deposit(double amount) {
  5. long stamp = lock.writeLock();
  6. try {
  7. balance = balance + amount;
  8. } finally {
  9. lock.unlockWrite(stamp);
  10. }
  11. }
  12. public double getBalance() {
  13. long stamp = lock.readLock();
  14. try {
  15. return balance;
  16. } finally {
  17. lock.unlockRead(stamp);
  18. }
  19. }
  20. }
复制代码

测试

  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支持

参考

What's New in JDK 8

如何在Java 8中愉快地处理日期和时间

上一篇:Java注解全面解析下一篇:JVM工作原理

最新评论

小黑屋|在路上 ( 蜀ICP备15035742号-1 

;

GMT+8, 2025-5-3 14:00

Copyright 2015-2025 djqfx

返回顶部