Stream API说明

为什么使用Stream API

什么是Stream

操作三步骤

创建Stream
方式一:集合

方式二:数组

方式三:Stream类的静态方法of()

方式四:创建无限流(了解)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| package com.stream.xzc;
import org.junit.Test;
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.IntStream; import java.util.stream.Stream;
public class Test1 { @Test public void test1(){ List<Employee> list = new ArrayList<>(); list.add(new Employee("A",20,1000)); list.add(new Employee("B",15,2000)); list.add(new Employee("C",20,3000)); list.add(new Employee("D",15,500)); Stream<Employee> stream = list.stream(); Stream<Employee> parallelStream = list.parallelStream(); }
@Test public void test2(){ int[] arr = new int[]{1,2,3,4,5,6}; IntStream intStream = Arrays.stream(arr);
Employee e1 = new Employee("E",20,1000); Employee e2 = new Employee("F",18,500); Employee[] arr2 = new Employee[]{e1,e2}; Stream<Employee> employeeStream = Arrays.stream(arr2);
}
@Test public void test3(){ Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6); } }
|
Stream的中间操作
筛选与切片

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| package com.stream.xzc;
import org.junit.Test;
import java.util.ArrayList; import java.util.List; import java.util.stream.Stream;
public class Test2 { @Test public void test1(){ List<Employee> list = new ArrayList<>(); list.add(new Employee("A",20,1000)); list.add(new Employee("B",15,2000)); list.add(new Employee("C",20,3000)); list.add(new Employee("D",15,500)); list.add(new Employee("E",20,2000)); Stream<Employee> stream = list.stream(); stream.filter(e -> e.getSalary() > 1000).forEach(System.out::println); System.out.println("================"); Stream<Employee> stream2 = list.stream(); stream2.limit(3).forEach(System.out::println); System.out.println("================"); Stream<Employee> stream3 = list.stream(); stream3.skip(3).forEach(System.out::println); System.out.println("================"); list.add(new Employee("F",20,1000)); list.add(new Employee("F",20,1000)); list.add(new Employee("F",20,1000)); System.out.println("去重前"); for (Employee e : list){ System.out.println(e); } System.out.println("去重后"); list.stream().distinct().forEach(System.out::println); }
}
|
Employee{name=’B’, age=15, salary=2000}
Employee{name=’C’, age=20, salary=3000}
Employee{name=’E’, age=20, salary=2000}
================
Employee{name=’A’, age=20, salary=1000}
Employee{name=’B’, age=15, salary=2000}
Employee{name=’C’, age=20, salary=3000}
================
Employee{name=’D’, age=15, salary=500}
Employee{name=’E’, age=20, salary=2000}
================
去重前
Employee{name=’A’, age=20, salary=1000}
Employee{name=’B’, age=15, salary=2000}
Employee{name=’C’, age=20, salary=3000}
Employee{name=’D’, age=15, salary=500}
Employee{name=’E’, age=20, salary=2000}
Employee{name=’F’, age=20, salary=1000}
Employee{name=’F’, age=20, salary=1000}
Employee{name=’F’, age=20, salary=1000}
去重后
Employee{name=’A’, age=20, salary=1000}
Employee{name=’B’, age=15, salary=2000}
Employee{name=’C’, age=20, salary=3000}
Employee{name=’D’, age=15, salary=500}
Employee{name=’E’, age=20, salary=2000}
Employee{name=’F’, age=20, salary=1000}
Stream的中间操作
映射

考察flatmap先考察这个


那么map就类似add,flagmap就类似addAll。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| package com.stream.xzc;
import org.junit.Test;
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Stream;
public class Test3 { @Test public void test(){ List<String> list = Arrays.asList("aa", "bb", "cc", "dd"); list.stream().map(String::toUpperCase).forEach(System.out::println); System.out.println("========================================"); List<Employee> list2 = new ArrayList<>(); list2.add(new Employee("A",20,1000)); list2.add(new Employee("B",15,2000)); list2.add(new Employee("C",20,3000)); list2.add(new Employee("D",15,500)); list2.add(new Employee("E",20,2000)); Stream<Employee> stream = list2.stream(); Stream<Integer> integerStream = stream.map(Employee::getSalary); integerStream.filter(s -> (s > 1000)).forEach(System.out::println);
System.out.println("======================================="); } public static Stream<Character> stringToCharacterStream(String s){ ArrayList<Character> list = new ArrayList<>(); for (Character c: s.toCharArray()){ list.add(c); } return list.stream(); } @Test public void test2(){ List<String> list = Arrays.asList("aa", "bb", "cc", "dd"); Stream<Stream<Character>> streamStream = list.stream().map(Test3::stringToCharacterStream); streamStream.forEach(s -> { s.forEach(System.out::println); }); System.out.println("=================================="); Stream<Character> characterStream = list.stream().flatMap(Test3::stringToCharacterStream); characterStream.forEach(System.out::println);
} }
|


map如果把流中的每一个元素映射成一个流,并返回一个由流构成的流,进行forEach就必须两层,一层lambda表达式,一层方法引用,此时可以用flatMap把里面的流打开,形成一对多的映射,返回一个一层流。
Stream的中间操作
排序

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package com.stream.xzc;
import org.junit.Test;
import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List;
public class Test4 { @Test public void test(){ List<Integer> list1 = Arrays.asList(123, 434, 54, 12, 1223, 50, 0); list1.stream().sorted().forEach(System.out::println);
List<Employee> list = new ArrayList<>(); list.add(new Employee("A",20,1000)); list.add(new Employee("B",15,2000)); list.add(new Employee("C",20,3000)); list.add(new Employee("D",15,500)); list.add(new Employee("E",20,2000)); list.stream().sorted(Comparator.comparingInt(Employee::getSalary).thenComparing(Employee::getAge)).forEach(System.out::println);
} }
|

Stream的终止操作
匹配与查找


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| package com.stream.xzc;
import org.junit.Test;
import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Optional; import java.util.stream.Stream;
public class Test5 { @Test public void test(){ List<Employee> list = new ArrayList<>(); list.add(new Employee("A",20,1000)); list.add(new Employee("B",15,2000)); list.add(new Employee("C",20,3000)); list.add(new Employee("D",15,500)); list.add(new Employee("E",20,2000)); Stream<Employee> stream = list.stream(); System.out.println(stream.allMatch(e -> e.getAge() > 18)); Stream<Employee> stream1 = list.stream(); System.out.println(stream1.anyMatch(e -> e.getSalary() >2000)); Stream<Employee> stream2 = list.stream(); System.out.println(stream2.noneMatch(e->e.getSalary() > 3000)); Stream<Employee> stream3 = list.stream(); Optional<Employee> first = stream3.findFirst(); System.out.println(first); Stream<Employee> stream4 = list.stream(); Optional<Employee> any = stream4.findAny(); System.out.println(any); Stream<Employee> stream5 = list.stream(); System.out.println(stream5.count()); Stream<Employee> stream6 = list.stream(); System.out.println(stream6.max(Comparator.comparingInt(Employee::getSalary))); Stream<Employee> stream7 = list.stream(); System.out.println(stream7.min(Comparator.comparingInt(Employee::getSalary))); } }
|

归约

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package com.stream.xzc;
import org.junit.Test;
import java.util.ArrayList; import java.util.Arrays; import java.util.List;
public class Test6 { @Test public void test(){ List<Integer> list1 = Arrays.asList(1,2,3,4,5,6,7,8,9,10); System.out.println(list1.stream().reduce(0,Integer::sum));
List<Employee> list = new ArrayList<>(); list.add(new Employee("A",20,1000)); list.add(new Employee("B",15,2000)); list.add(new Employee("C",20,3000)); list.add(new Employee("D",15,500)); list.add(new Employee("E",20,2000));
System.out.println(list.stream().map(Employee::getSalary).reduce(Integer::sum)); } }
|

收集
收集也就是流转集合


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.stream.xzc;
import org.junit.Test;
import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors;
public class Test7 { @Test public void test(){ List<Employee> list = new ArrayList<>(); list.add(new Employee("A",20,1000)); list.add(new Employee("B",15,2000)); list.add(new Employee("C",20,3000)); list.add(new Employee("D",15,500)); list.add(new Employee("E",20,2000));
List<Employee> collect = list.stream().filter(e -> e.getSalary() > 1000).collect(Collectors.toList()); System.out.println(collect); } }
|

Optional类


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.optional.xzc; import com.stream.xzc.Employee;
import java.util.Optional;
public class Test { @org.junit.Test public void test(){ Employee e = new Employee("hawkeye",10,1000); Optional<Employee> o = Optional.of(e); System.out.println(o); Employee e1 = null; Optional<Employee> o1 = Optional.ofNullable(e1); System.out.println(o1); Optional<Employee> o2 = Optional.empty(); System.out.println(o2); } }
|

Optional使用举例
新建一个Dog类和一个Person类


不用Optional类时,我们这样通过Person获得Dog的名字
1 2 3 4 5 6 7 8 9
| public String getDogName(Person p){ if(p!=null){ Dog d = p.getDog(); if(d!=null){ return d.getName(); } } return null; }
|
先看一下orElse方法的作用,形参就是一个备胎。



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package com.optional.xzc;
import org.junit.Test;
import java.util.Optional;
public class Test2 { @Test public void test(){ Person p1 = new Person("p1",new Dog()); Person p2 = null; Person p3 = new Person("p3",new Dog("p3's dog")); Person p4 = new Person("p4",null); System.out.println(getDogName(p1)); System.out.println(getDogName(p2)); System.out.println(getDogName(p3)); System.out.println(getDogName(p4)); } public static String getDogName(Person p){ Optional<Person> optionalPerson = Optional.ofNullable(p); Person hawkeye = optionalPerson.orElse(new Person("Hawkeye", new Dog("Hawkeye's dog"))); Optional<Dog> optionalDog = Optional.ofNullable(hawkeye.getDog()); Dog dog = optionalDog.orElse(new Dog("绝对非空的dog")); return dog.getName(); }
}
|

p1人存在,也有狗,只不过狗是空参构造,所以没名字
p2人不存在,给了一个备胎 hawkeye,他有狗
p3人存在,也有狗,狗有名字
p4人存在,但狗指定为null,即不存在,走到了最后一层。
这里主要是注意使用orElse方法,使用get方法会抛异常。
get可以和of方法搭配,orElse和ofNullable搭配。
当然也可以用isPresent先判断是不是空。