JDK8新特性

https://blog.csdn.net/CrankZ/article/details/81355643

Lambda

  • 如果我们提供的这个接口包含一个以上的Abstract Method,那么使用lambda表达式则会报错。 
    • 只能有一个

日期

  • Java 8 在 java.time 包下提供了很多新的 API
    • Local(本地) − 简化了日期时间的处理,没有时区的问题。
    • Zoned(时区) − 通过制定的时区处理日期时间。
    • 新的java.time包涵盖了所有处理日期,时间,日期/时间,时区,时刻(instants),过程(during)与时钟(clock)的操作。
  • 所有类都是不可变的、线程安全的
    • java.time – 包含值对象的基础包
      java.time.chrono – 提供对不同的日历系统的访问
      java.time.format – 格式化和解析时间和日期
      java.time.temporal – 包括底层框架和扩展特性
      java.time.zone – 包含时区支持的类

Optional

  • Optional 类是一个可以为null的容器对象。

    • 如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

    • Optional 类的引入很好的解决空指针异常。

Base64

  • Java 8 内置了 Base64 编码的编码器和解码器
    • 基本:输出被映射到一组字符A-Za-z0-9+/
      • 编码不添加任何行标
      • 输出的解码仅支持A-Za-z0-9+/
    • URL输出映射到一组字符A-Za-z0-9+_,输出是URL和文件。
    • MIME输出隐射到MIME友好格式。
      • 输出每行不超过76字符,并且使用'\r'并跟随'\n'作为分割。
      • 编码输出最后没有行分割。

HashMap的改进

接口的默认方法和静态方法

  • 简单说,默认方法就是接口可以有实现方法,
    • 而且不需要实现类去实现其方法。
    • 只需在方法名前面加个default关键字即可实现默认方法。
    • public interface Vehicle {
         default void print(){
            System.out.println("我是一辆车!");
         }
      }
      
      • 为什么要有这个特性?

        • 以前当需要修改接口时候,需要修改全部实现该接口的类。
    • 多个默认方法
      • 
        public interface Vehicle {
           default void print(){
              System.out.println("我是一辆车!");
           }
        }
        public interface FourWheeler {
           default void print(){
              System.out.println("我是一辆四轮车!");
           }
        }
        
        //...
        
        //解决办法1:
        public class Car implements Vehicle, FourWheeler {
           default void print(){
              System.out.println("我是一辆四轮汽车!");
           }
        }
        
        //解决办法2:
        public class Car implements Vehicle, FourWheeler {
           public void print(){
              Vehicle.super.print();
           }
        }
        
        
    • 静态默认方法
      • @Test
        public void interfaceDefaultTest() {
            Vehicle vehicle = new Car();
            vehicle.print();
        }
         
        interface Vehicle {
            default void print() {
                System.out.println("我是一辆车!");
            }
         
            static void blowHorn() {
                System.out.println("按喇叭!!!");
            }
        }
         
        interface FourWheeler {
            default void print() {
                System.out.println("我是一辆四轮车!");
            }
        }
         
        class Car implements Vehicle, FourWheeler {
            public void print() {
                Vehicle.super.print();
                FourWheeler.super.print();
                Vehicle.blowHorn();
                System.out.println("我是一辆汽车!");
            }
        }

         

Stream

  • Java 8 API添加了一个新的抽象称为流Stream,
    • 可以让你以一种声明的方式处理数据。
    • 提供一种对 Java 集合运算和表达的高阶抽象。
    • 这种风格将要处理的元素集合看作一种流,
      • 流在管道中传输,
      • 并且可以在管道的节点上进行处理,
      • 比如筛选, 排序,聚合等。
  • Stream API可以提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
    • List<Integer> transactionsIds =
      widgets.stream()
          .filter(b -> b.getColor() == RED)
          .sorted((x,y) -> x.getWeight() - y.getWeight())
          .mapToInt(Widget::getWeight)
          .sum();
      

       

    • 在 Java 8 中, 集合接口有两个方法来生成流:

      • stream():为集合创建串行流。
      • parallelStream():为集合创建并行流。
    • forEach
      • 使用 forEach 输出了10个随机数:
        • @Test
          public void streamRandomTest() {
              Random random = new Random();
              random.ints().limit(10).forEach(System.out::println);
          }
          
    • 中间操作

      • map(映射)

        • //map 方法用于映射每个元素到对应的结果
          @Test
          public void streamMapTest() {
              List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
              // 获取对应的平方数
              List<Integer> squaresList = numbers.stream()
                      .map(i -> i * i)
                      .distinct()
                      .collect(Collectors.toList());
           
              for (int x : squaresList) {
                  System.out.println(x);
              }
          }
          
      • Filter(过滤)

        • //filter 方法用于通过设置的条件过滤出元素
          @Test
          public void streamFilterTest() {
              List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
              // 获取空字符串的数量
              long count = strings.stream().filter(string -> string.isEmpty()).count();
              System.out.println(count);
          }
          
      • Limit(限制)

        • //用于获取指定数量的流。
          @Test
          public void streamLimitTest() {
              Random random = new Random();
              random.ints().limit(10).forEach(System.out::println);
          }
      • Sorted(排序)

        • //Sorted 方法用于对流进行排序
          @Test
          public void streamSortedTest() {
              Random random = new Random();
              random.ints().limit(10).sorted().forEach(System.out::println);
          }
    • 最终操作

      • Match(匹配)

        • 用来判断某个predicate是否和流对象相匹配,最终返回Boolean类型结果
        • @Test
          public void streamMatchTest() {
              List<String> list = new ArrayList<String>();
              list.add("a1");
              list.add("b1");
           
              // 流对象中只要有一个元素匹配就返回true
              boolean anyStartWithA = list.stream().anyMatch((s -> s.startsWith("a")));
              System.out.println(anyStartWithA);
              // 流对象中每个元素都匹配就返回true
              boolean allStartWithA = list.stream().allMatch((s -> s.startsWith("a")));
              System.out.println(allStartWithA);
          }
          
      • Collectors(收集)

        • Collectors 类实现了很多归约操作,
          • 例如将流转换成集合和聚合元素。
          • Collectors 可用于返回列表或字符串:
        • @Test
          public void streamCollectorsTest() {
              List<String> strings = 
                   Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
              List<String> filtered = 
                   strings.stream()
                          .filter(string -> !string.isEmpty())
                          .collect(Collectors.toList());
              System.out.println("筛选列表: " + filtered);
              String mergedString = 
                   strings.stream()
                          .filter(string -> !string.isEmpty())
                          .collect(Collectors.joining(", "));
              System.out.println("合并字符串: " + mergedString);
          }
          

 

  • 统计
    • 一些产生统计结果的收集器也非常有用。
      • 它们主要用于int、double、long等基本类型上,
      • 它们可以用来产生类似如下的统计结果。
    • @Test
      public void streamCollectorsTest2() {
          List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
          IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
          System.out.println("列表中最大的数 : " + stats.getMax());
          System.out.println("列表中最小的数 : " + stats.getMin());
          System.out.println("所有数之和 : " + stats.getSum());
          System.out.println("平均数 : " + stats.getAverage());
      }
      
  • Count(计数)

    • 类似sql的count,用来统计流中元素的总数
  • Reduce(规约)

    • reduce方法允许我们用自己的方式去计算元素或者将一个Stream中的元素以某种规律关联,
      • @Test
        public void streamReduceTest() {
            List<String> strings = Arrays.asList("a", "b", "c");
            strings.stream().sorted().reduce((s1, s2) -> {
                System.out.println(s1 + "|" + s2);
                return s1 + "|" + s2;
            });
        }
        
    • parallel(并行)

      • parallelStream 是流并行处理程序的代替方法。
      • 以下实例我们使用 parallelStream 来输出空字符串的数量:
      • @Test
        public void parallelStreamTest() {
            List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
            // 获取空字符串的数量
            long count = strings.parallelStream().filter(string -> string.isEmpty()).count();
            System.out.println(count);
        }
        

并行Stream VS 串行Stream

  • 并行Stream基于Fork-join并行分解框架实现,
    • 将大数据集合切分为多个小数据结合交给不同的线程去处理,
    • 这样在多核处理情况下,性能会得到很大的提高。
    • @Test
      public void parallelCompare() {
          // 创建一个较大的集合
          List<String> bigLists = new ArrayList<>();
          for (int i = 0; i < 10000000; i++) {
              UUID uuid = UUID.randomUUID();
              bigLists.add(uuid.toString());
          }
          notParallelStreamSortedTest(bigLists);
          parallelStreamSortedTest(bigLists);
      }
       
      // 不使用并行操作
      private void notParallelStreamSortedTest(List<String> bigLists) {
          long startTime = System.nanoTime();
          long count = bigLists.stream().sorted().count();
          long endTime = System.nanoTime();
          long millis = TimeUnit.NANOSECONDS.toMillis(endTime - startTime);
          System.out.println(System.out.printf("串行排序: %d ms", millis));
      }
       
      // 使用并行操作
      private static void parallelStreamSortedTest(List<String> bigLists) {
          long startTime = System.nanoTime();
          long count = bigLists.parallelStream().sorted().count();
          long endTime = System.nanoTime();
          long millis = TimeUnit.NANOSECONDS.toMillis(endTime - startTime);
          System.out.println(System.out.printf("并行排序: %d ms", millis));
      }
    • ​​​​​​​
  • 如果你现在还是单核处理器,而数据量又不算很大的情况下,串行流仍然是这种不错的选择。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值