Java 8 新特性

Java 8

  • Java 8 允许您通过::关键字传递方法或构造函数的引用。

Lambda 表达式

java 复制代码
List<String> names = Arrays.asList("banana", "apple", "orange","fruit","grape");
// 老版本Java排列字符串
Collections.sort(names, new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return a.compareTo(b);
    }
});

// Java 8 匿名函数的方式
Collections.sort(names, (String a, String b) -> {
    return a.compareTo(b);
});
// 以上可以简写为如下
Collections.sort(names, (String a, String b) -> a.compareTo(b));
// List的sort方法
names.sort((a, b) -> a.compareTo(b));

函数式接口(Functional Interfaces)

  • 只包含一个抽象的方法,但可以有多个非抽象方法的接口,可以隐式转换为lambda表达式,一般以@FunctionalInterface进行标记,如下两个例子。

    • java.lang.Runnable
    • java.util.concurrent.Callable
  • 内置的函数式接口

    • Predicate 接口是只有一个参数的返回布尔类型值的 断言型 接口。

    • Function接口接受一个参数并生成结果。

    • Supplier接口产生给定泛型类型的结果。

    • Consumer 接口表示要对单个输入参数执行的操作。

    • Comparator是老 Java 中的经典接口, Java 8 在此之上添加了多种默认方法。

Optional

java 复制代码
// 获取值,没有时返回默认值
Optional.ofNullable(u).map(user->user.name).orElse("Unknown");

// 多层取值,没有时异常提示
Optional.ofNullable(comp).map(Competition::getResult).map(User::getName).orElseThrow(()->new IllegalArgumentException("The value of param comp isn't available."));

// 过滤,获取不到时异常提示
Optional.ofNullable(name).filter(User::isNameValid).orElseThrow(()->new IllegalArgumentException("Invalid username"));

Streams

java 复制代码
List<String> strList = new ArrayList<>();
strList.add("one");
strList.add("two");
strList.add("three");
strList.add("four");
strList.add("five");
strList.add("six");
strList.add("seven");
strList.add("eight");

Filter(过滤)

java 复制代码
strList = strList.stream().filter(i->"one".equals(i)).collect(Collectors.toList());

Sorted(排序)

java 复制代码
strList = strList.stream().filter(i->"one".equals(i))
                .sorted(Comparator.comparing(Function.identity()))
                .collect(Collectors.toList());

Map(转换对象)

java 复制代码
// map
strList = strList.stream().filter(i->"one".equals(i))
                .map(String::toUpperCase).filter(Objects::nonNull).distinct()
                .sorted(Comparator.comparing(Function.identity()))
			    .collect(Collectors.toList());

// flatMap 
List<String> strList = new ArrayList<>();
strList.add("one");
strList.add("two");

List<String> strList2 = new ArrayList<>();
strList2.add("five");
strList2.add("six");

List<List<String>> list = new ArrayList<>();
list.add(strList);
list.add(strList2);

List<String> allList = list.stream().flatMap(Collection::stream).collect(Collectors.toList());

// Collectors.toMap
Map<String, String> greenPayMap = poList.stream().collect(Collectors.toMap(OrderPO::getPid, OrderPO::getGreenPay, (o, n) -> o));
// (o, n) -> o) 处理重复的`Key`,避免当出现相同 `Key`值时会抛出 `IllegalStateException` 异常。

// Collectors.groupingBy
Map<String, List<OrderDetailPO>> detailMap = detailList.stream().collect(Collectors.groupingBy(OrderDetailPO::getPid));

Match(匹配)

java 复制代码
// 是否全匹配
strList.stream().allMatch(i->i.startsWith("o"));
// 是否有一个匹配
strList.stream().anyMatch(i->i.startsWith("o"));
// 是否全部不匹配
strList.stream().noneMatch(i->i.startsWith("o"));

Count(计数)

java 复制代码
strList.stream().filter(i->"one".equals(i)).count();

Reduce(规约)

java 复制代码
// 字符串连接,concat = "ABCD"
String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat);
// 求最小值,minValue = -3.0
double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min);
// 求和,sumValue = 10, 有起始值
int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);
// 求和,sumValue = 10, 无起始值
sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();

Collectors

java 复制代码
// 1、分组
Map<String, List<User>> cityMap = users.stream().collect(Collectors.groupingBy(User::getCity));

// 2、分组并计数
Map<String, Long> countByCity = users.stream().collect(Collectors.groupingBy(User::getCity, Collectors.counting()));

// 3、分组并求平均值
Map<String, Double> i = users.stream().collect(Collectors.groupingBy(User::getCity, Collectors.averagingInt(User::getScore)));  

// 4、拼接
String str = Stream.of("A", "B", "C", "D").collect(Collectors.joining());

// 5、Collectors.mapping
List<String> names = people.stream().collect(Collectors.mapping(Person::getName, Collectors.toList()));