Java 8 新特性

基本概念

流是Java8引入的全新概念,它用来处理集合中的数据,暂且可以把它理解为一种高级集合。

众所周知,集合操作非常麻烦,若要对集合进行筛选、投影,需要写大量的代码,而流是以声明的形式操作集合,它就像SQL语句,我们只需告诉流需要对集合进行什么操作,它就会自动进行操作,并将执行结果交给你,无需我们自己手写代码。

因此,流的集合操作对我们来说是透明的,我们只需向流下达命令,它就会自动把我们想要的结果给我们。由于操作过程完全由Java处理,因此它可以根据当前硬件环境选择最优的方法处理,我们也无需编写复杂又容易出错的多线程代码了。

流的操作种类 

流的操作分为两种,分别为中间操作 和 终端操作。

中间操作
当数据源中的数据上了流水线后,这个过程对数据进行的所有操作都称为“中间操作”。
中间操作仍然会返回一个流对象,因此多个中间操作可以串连起来形成一个流水线。

终端操作
当所有的中间操作完成后,若要将数据从流水线上拿下来,则需要执行终端操作。
终端操作将返回一个执行结果,这就是你想要的数据。

示例

List<Person> result = list.stream()
                    .filter(Person::isStudent)
                    .collect(toList());

List<Person> result = list.stream()
                    .distinct()
                    .collect(toList());

List<Person> result = list.stream()
                    .limit(3)
                    .collect(toList());

List<Person> result = list.stream()
                    .skip(3)
                    .collect(toList());

// 映射
List<String> result = list.stream()
                    .map(Person::getName)
                    .collect(toList());


//合并多个流
List<String> list = new ArrayList<String>();
list.add("I am a boy");
list.add("I love the girl");
list.add("But the girl loves another girl");

list.stream()
            .map(line->line.split(" "))
            .flagmap(Arrays::stream)
            .distinct()
            .collect(toList());

//
anyMatch
boolean result = list.stream() .anyMatch(Person::isStudent);
boolean result = list.stream() .allMatch(Person::isStudent);
boolean result = list.stream() .noneMatch(Person::isStudent);
Optional<Person> person = list.stream().findAny();

Optional介绍

Optional是Java8新加入的一个容器,这个容器只存1个或0个元素,它用于防止出现NullpointException,它提供如下方法:

isPresent()
判断容器中是否有值。
ifPresent(Consume lambda)
容器若不为空则执行括号中的Lambda表达式。
T get()
获取容器中的元素,若容器为空则抛出NoSuchElement异常。
T orElse(T other)
获取容器中的元素,若容器为空则返回括号中的默认值。

Optional<Person> person = list.stream().findFirst();

归约

归约是将集合中的所有元素经过指定运算,折叠成一个元素输出,如:求最值、平均数等,这些操作都是将一个集合的元素折叠成一个元素输出。

在流中,reduce函数能实现归约。


reduce函数接收两个参数:

初始值

进行归约操作的Lambda表达式

// 元素求和:自定义Lambda表达式实现求和
int age = list.stream().reduce(0, (person1,person2)->person1.getAge()+person2.getAge());

// 元素求和:使用Integer.sum函数求和
int age = list.stream().reduce(0, Integer::sum);

收集器

 收集器用来将经过筛选、映射的流进行最后的整理,可以使得最后的结果以不同的形式展现。

collect方法即为收集器,它接收Collector接口的实现作为具体收集器的收集方法。

Collector接口提供了很多默认实现的方法,我们可以直接使用它们格式化流的结果;也可以自定义Collector接口的实现,从而定制自己的收集器。

long count = list.stream()
                    .collect(Collectors.counting());

示例

List to Map

public class TestDuplicatedKey {

    public static void main(String[] args) {

        List<Hosting> list = new ArrayList<>();
        list.add(new Hosting(1, "liquidweb.com", 80000));
        list.add(new Hosting(2, "linode.com", 90000));
        list.add(new Hosting(3, "digitalocean.com", 120000));
        list.add(new Hosting(4, "aws.amazon.com", 200000));
        list.add(new Hosting(5, "mkyong.com", 1));

        list.add(new Hosting(6, "linode.com", 100000)); // new line

        // key = name, value - websites , but the key 'linode' is duplicated!?
        Map<String, Long> result1 = list.stream().collect(
                Collectors.toMap(Hosting::getName, Hosting::getWebsites));

        System.out.println("Result 1 : " + result1);

    }
}
public class TestSortCollect {

    public static void main(String[] args) {

        List<Hosting> list = new ArrayList<>();
        list.add(new Hosting(1, "liquidweb.com", 80000));
        list.add(new Hosting(2, "linode.com", 90000));
        list.add(new Hosting(3, "digitalocean.com", 120000));
        list.add(new Hosting(4, "aws.amazon.com", 200000));
        list.add(new Hosting(5, "mkyong.com", 1));
        list.add(new Hosting(6, "linode.com", 100000));

        //example 1
        Map result1 = list.stream()
                .sorted(Comparator.comparingLong(Hosting::getWebsites).reversed())
                .collect(
                        Collectors.toMap(
                                Hosting::getName, Hosting::getWebsites, // key = name, value = websites
                                (oldValue, newValue) -> oldValue,       // if same key, take the old key
                                LinkedHashMap::new                      // returns a LinkedHashMap, keep order
                        ));

        System.out.println("Result 1 : " + result1);

    }
}
List<FieldSetting> fieldSettingList = getFieldSetting(model);
// key为对象的一个属性, value为原对象 Map
<String, FieldSetting> fieldSettings = fieldSettingList.stream().collect(Collectors.toMap(FieldSetting::getFieldName,f -> f));

链接

Java8新特性——StreamAPI(一)

Java8新特性——StreamAPI(二)

Java 8 将List转换为Map

原文地址:https://www.cnblogs.com/tonyq/p/8205972.html