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'作为分割。
- 编码输出最后没有行分割。
- 基本:输出被映射到一组字符A-Za-z0-9+/
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); }
-
- 使用 forEach 输出了10个随机数:
-
中间操作
-
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); }
- Collectors 类实现了很多归约操作,
-
-
- 统计
- 一些产生统计结果的收集器也非常有用。
- 它们主要用于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); }
- reduce方法允许我们用自己的方式去计算元素或者将一个Stream中的元素以某种规律关联,
并行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)); }
-
- 如果你现在还是单核处理器,而数据量又不算很大的情况下,串行流仍然是这种不错的选择。