Java 8 中的 Streams API

转载自 https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/index.html

一、什么是流
Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,用户只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。

Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。

而和迭代器又不同的是,Stream 可以并行化操作,迭代器只能命令式地、串行化操作。顾名思义,当使用串行方式去遍历时,每个 item 读完后再读下一个 item。而使用并行去遍历时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。Stream 的并行操作依赖于 Java7 中引入的 Fork/Join 框架(JSR166y)来拆分任务和加速处理过程。
二、流的分类
1、Intermediate:一个流可以后面跟随零个或多个 intermediate 操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。这类操作都是惰性化的(lazy),就是说,仅仅调用到这类方法,并没有真正开始流的遍历。
2、Terminal:一个流只能有一个 terminal 操作,当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。Terminal 操作的执行,才会真正开始流的遍历,并且会生成一个结果,或者一个 side effect。
二、流的操作
流常用的操作可归为以下:
1、Intermediate:map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered
2、Terminal :forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator
3、Short-circuiting:anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit
三、Stream的使用

public class Person {
private String name;
private Integer age;
private String city;
private String gender;

public Person(String name, Integer age, String city,String gender) {
    this.name = name;
    this.age = age;
    this.city = city;
    this.gender = gender;
}
}


public class StreamTest {
private static List personList = new ArrayList<>();
@Before
public void setUp(){
    Person person1 = new Person("Lisa" ,19,"杭州","女");
    Person person2 = new Person("Jacob",  24,"杭州","男");
    Person person3 = new Person("Bob", 15,"杭州","男");
    Person person4 = new Person("Michael",20,"杭州","男");
    Person person5 = new Person("Michael",  22,"杭州","男");
    Person person6 = new Person("Kate",  20,"杭州","女");
    personList.add(person1);
    personList.add(person2);
    personList.add(person3);
    personList.add(person4);
    personList.add(person5);
    personList.add(person6);
    personList.add(person6);
}

@Test
public void testIntermediate(){
    System.out.println("年龄加1");
    personList.stream().map(person -> {
        person.setAge(person.getAge() + 1);
        return person;
    }).forEach(System.out::println);
    System.out.println("------------------分界线-----------------");
    System.out.println("年龄加1");
    personList.stream().peek(person -> person.setAge(person.getAge() + 1 )).forEach(System.out::println);

    System.out.println("------------------分界线-----------------");
    System.out.println("只打印年龄");
    personList.stream().mapToInt(Person::getAge).forEach(System.out::println);

    System.out.println("------------------分界线-----------------");
    System.out.println("只打印年龄大于25的人");
    personList.stream().filter(person -> person.getAge() > 25).forEach(System.out::println);

    System.out.println("------------------分界线-----------------");
    System.out.println("去掉重复的人");
    personList.stream().distinct().forEach(System.out::println);

    System.out.println("------------------分界线-----------------");
    System.out.println("按年龄排序");
    personList.stream().sorted((p1,p2) -> {
        if (p1.getAge() >= p2.getAge()){
            return 0;
        }else {
            return -1;
        }
    }).forEach(System.out::println);

    System.out.println("------------------分界线-----------------");
    System.out.println("只打印前两个");
    personList.stream().limit(2).forEach(System.out::println);


    System.out.println("------------------分界线-----------------");
    System.out.println("跳过指定元素");
    personList.stream().skip(1).forEach(System.out::println);
}

@Test
public void testTerminal(){
    Person defaultPerson = new Person("default",0,"default","default");

    System.out.println("------------------分界线-----------------");
    System.out.println("获取年龄最大的人");
    Person person = personList.stream().reduce((person1, person2) -> {
        if (person1.getAge() > person2.getAge()){
            return person1;
        }else {
            return person2;
        }
    }).orElse(defaultPerson);
    System.out.println(person);

    System.out.println("------------------分界线-----------------");
    System.out.println("stream转换成集合");
    personList.stream().collect(Collectors.toList()).forEach(System.out::println);

    System.out.println("------------------分界线-----------------");
    System.out.println("查找最小年龄的人");
    person = personList.stream().min((o1, o2) -> {
        if (o1.getAge() > o2.getAge()){
            return 1;
        }else {
            return -1;
        }
    }).orElse(defaultPerson);
    System.out.println(person);

    System.out.println("------------------分界线-----------------");
    System.out.println("查找最大年龄的人");
    person = personList.stream().max((o1, o2) -> {
        if (o1.getAge() > o2.getAge()){
            return 1;
        }else {
            return -1;
        }
    }).orElse(defaultPerson);
    System.out.println(person);

    System.out.println("------------------分界线-----------------");
    System.out.println("流的长度");
    long size = personList.stream().count();
    System.out.println(size);


    System.out.println("------------------分界线-----------------");
    System.out.println("是否存在年龄位20的人");
    boolean result = personList.stream().anyMatch(person1 -> person1.getAge() == 20);
    System.out.println(result);

    System.out.println("------------------分界线-----------------");
    System.out.println("所有年龄是否都为20");
    result = personList.stream().allMatch(person1 -> person1.getAge() == 20);
    System.out.println(result);

    System.out.println("------------------分界线-----------------");
    System.out.println("所有年龄不存在20的人");
    result = personList.stream().noneMatch(person1 -> person1.getAge() == 20);
    System.out.println(result);


    System.out.println("------------------分界线-----------------");
    System.out.println("在并行过程中找到满足条件的人");
    person = personList.stream().filter(person1 -> person1.getAge() > 19).findFirst().orElse(defaultPerson);
    System.out.println(person);

    System.out.println("------------------分界线-----------------");
    System.out.println("在并行过程中找到满足条件的人");
    person = personList.stream().filter(person1 -> person1.getAge() > 19).findAny().orElse(defaultPerson);
    System.out.println(person);


}

`

你可能感兴趣的:(java)