流是一个新的抽象层中引入Java8。使用流,可以处理数据的声明方式类似于SQL语句。例如,考虑下面的SQL语句。
SELECT max(salary), employee_id, employee_name FROM Employee
上面的SQL表达式自动返回最大的受薪雇员的详细信息,没有做任何计算。使用集合框架在Java中,开发人员必须使用循环和重复检查。另一个问题是效率;随着多核处理器可用自在,Java开发人员编写并行代码处理,但是很容易出错。
为了解决这些问题,java引入了stream的概念,允许开发人员以声明的方式处理数据,利用多核架构,而不需要编写任何特定的代码。
什么是Stream
流代表一个对象从源序列,支持聚合操作。以下是流的特点
- 元素序列:流提供了一组特定类型的元素的顺序。一个流/计算元素的需求。它永远不会存储元素。
- 数据来源:集合,数组,I/O资源,input
- 聚合操作:Stream支持聚合操作包括filter,map,limit,reduce,find,match等等
- 管道:大多数的流操作返回流本身,因此他们可以管线式结果。这些操作称为中间操作,其功能是将输入、过程,并返回输出目标。collect()方法是一个管道结束时的操作,标志着流的结束。
- 自动迭代:Stream支持内置的forEach迭代
api demo
- stream() − Returns a sequential stream considering collection as its source.
- parallelStream() − Returns a parallel Stream considering collection as its source.
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
- forEach - Stream has provided a new method ‘forEach’ to iterate each element of the stream. The following code segment shows how to print 10 random numbers using forEach.
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
- map - The ‘map’ method is used to map each element to its corresponding result. The following code segment prints unique squares of numbers using map.
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
//get list of unique squares
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
- filter - The ‘filter’ method is used to eliminate elements based on a criteria. The following code segment prints a count of empty strings using filter.
List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
//get count of empty string
int count = strings.stream().filter(string -> string.isEmpty()).count();
- limit - The ‘limit’ method is used to reduce the size of the stream. The following code segment shows how to print 10 random numbers using limit.
Random random = new Random();
random.ints().limit(10).forEach(System.out::println);
- sorted - The ‘sorted’ method is used to sort the stream. The following code segment shows how to print 10 random numbers in a sorted order.
Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);
- Parallel Processing - parallelStream is the alternative of stream for parallel processing. Take a look at the following code segment that prints a count of empty strings using parallelStream.
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
//get count of empty string
long count = strings.parallelStream().filter(string -> string.isEmpty()).count();
It is very easy to switch between sequential and parallel streams.
- Collectors - Collectors are used to combine the result of processing on the elements of a stream. Collectors can be used to return a list or a string.
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 List: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("Merged String: " + mergedString);
- Statistics - With Java 8, statistics collectors are introduced to calculate all statistics when stream processing is being done.
List numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("Highest number in List : " + stats.getMax());
System.out.println("Lowest number in List : " + stats.getMin());
System.out.println("Sum of all numbers : " + stats.getSum());
System.out.println("Average of all numbers : " + stats.getAverage());