Java 8 - Streams

本文深入探讨Java8的Stream API,介绍其基本概念、特性及如何进行声明式数据处理,对比传统迭代方式,展示Stream在处理集合数据时的高效性和简洁性。通过多个示例,演示如何使用Stream进行过滤、映射、排序、统计等操作。

流(Strams)是Java 8引入的一种新的抽象层,流可以使用声明式的方法处理集合元素,就像SQL一样下面的声明式语句一样:

SELECT max(salary), employee_id, employ_name FROM Employee

上面的SQL返回薪水最高的员工的详细信息,在Java中你必须在循环中一一比较才能获得结果,而SQL的声明式语句你不用去对数据一一比较;Java 8引入Stream的另一个目的是效率,现在多核处理器已经很普遍了,但让Java开发人员写并行计算费时费力,而且很容易错误。
Java 8引入Stream,可以很容易写出直观易懂的代码,同时也可以使用并行来提高运行效率。

什么是Stream?

Stream指一组可以进行“聚集”操作的有序对象。他有一下特性:

  • 一组有序元素 - 是一组相同元素的集合序列,可以获取、统计元素,但不存储元素。
  • - Stream源可以是Collection、Arrays或I/O资源。
  • 集合操作 - Stream支持集合操作如filter、map、limit、reduce、find、match等等。
  • 流水线(Pipelining) - 多数Stream操作返回Stream本身,所以可以将Stream操作连起来组成流水线。这样可以对操作进行优化,如延迟执行、短路计算等。而像collect()方法是一个终止流的方法,放在流水线最后,用于获得处理后的结果集。
  • 内部迭代(Automatic iterations) - 以前对集合迭代是通过Iterator或for循环的方式,在集合外部操作,叫做外部迭代。Stream提供内部迭代方式,通过观察者模式(Visitor)实现。
获得Stream

Java 8 Collection提供了两个方法获得Stream。

  • stream() - 串行化流:串行化执行操作。
  • parallelStream() - 并行化流:流并行处理。
List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
forEach

Stream提供forEach方法来遍历元素。下面的程序打印10个随机数。

Random random = new Random();
random.ints().limit(10).forEach(System.out.println)
map

map方法在每一个元素上进行相应的操作。下面的程序无重复的计算每个元素的平方。

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
//get list of unique squares
List<Integer> squareList = numbers.stream().map(i -> i*i).distinct().collection(Collections.toList());
filter

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

limit方法用于限制stream元素的数目。下面的程序下面的程序打印10个随机数。

Random random = new Random();
random.ints().limit(10).forEach(System.out.println)
sorted

sorted()方法排序stream元素。下面的程序打印10个有序的随机数。

Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);
Parallel Processing

parallelStream是并行处理的一种选择。下面的程序返回空字符串的数目。

ist<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
//get count of empty string
long count = strings.parallelStream().filter(string -> string.isEmpty()).count();
Collections

Collections用于聚合stream处理结果,可以返回一个list或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

statistic collectors再stream处理完成后,用于计算一些统计结果。

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());
Stream示例
import java.util.ArrayList;
import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.Map;

public class Java8Tester {

  public static void main(String args[]) {
     System.out.println("Using Java 7: ");
   	
     // Count empty strings
     List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
     System.out.println("List: " +strings);
     long count = getCountEmptyStringUsingJava7(strings);
   	
     System.out.println("Empty Strings: " + count);
     count = getCountLength3UsingJava7(strings);
   	
     System.out.println("Strings of length 3: " + count);
   	
     //Eliminate empty string
     List<String> filtered = deleteEmptyStringsUsingJava7(strings);
     System.out.println("Filtered List: " + filtered);
   	
     //Eliminate empty string and join using comma.
     String mergedString = getMergedStringUsingJava7(strings,", ");
     System.out.println("Merged String: " + mergedString);
     List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
   	
     //get list of square of distinct numbers
     List<Integer> squaresList = getSquares(numbers);
     System.out.println("Squares List: " + squaresList);
     List<Integer> integers = Arrays.asList(1,2,13,4,15,6,17,8,19);
   	
     System.out.println("List: " +integers);
     System.out.println("Highest number in List : " + getMax(integers));
     System.out.println("Lowest number in List : " + getMin(integers));
     System.out.println("Sum of all numbers : " + getSum(integers));
     System.out.println("Average of all numbers : " + getAverage(integers));
     System.out.println("Random Numbers: ");
   	
     //print ten random numbers
     Random random = new Random();
   	
     for(int i = 0; i < 10; i++) {
        System.out.println(random.nextInt());
     }
   	
     System.out.println("Using Java 8: ");
     System.out.println("List: " +strings);
   	
     count = strings.stream().filter(string->string.isEmpty()).count();
     System.out.println("Empty Strings: " + count);
   	
     count = strings.stream().filter(string -> string.length() == 3).count();
     System.out.println("Strings of length 3: " + count);
   	
     filtered = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.toList());
     System.out.println("Filtered List: " + filtered);
   	
     mergedString = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.joining(", "));
     System.out.println("Merged String: " + mergedString);
   	
     squaresList = numbers.stream().map( i ->i*i).distinct().collect(Collectors.toList());
     System.out.println("Squares List: " + squaresList);
     System.out.println("List: " +integers);
   	
     IntSummaryStatistics stats = integers.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());
     System.out.println("Random Numbers: ");
   	
     random.ints().limit(10).sorted().forEach(System.out::println);
   	
     //parallel processing
     count = strings.parallelStream().filter(string -> string.isEmpty()).count();
     System.out.println("Empty Strings: " + count);
  }
   
  private static int getCountEmptyStringUsingJava7(List<String> strings) {
     int count = 0;

     for(String string: strings) {
   	
        if(string.isEmpty()) {
           count++;
        }
     }
     return count;
  }
   
  private static int getCountLength3UsingJava7(List<String> strings) {
     int count = 0;
   	
     for(String string: strings) {
   	
        if(string.length() == 3) {
           count++;
        }
     }
     return count;
  }
   
  private static List<String> deleteEmptyStringsUsingJava7(List<String> strings) {
     List<String> filteredList = new ArrayList<String>();
   	
     for(String string: strings) {
   	
        if(!string.isEmpty()) {
            filteredList.add(string);
        }
     }
     return filteredList;
  }
   
  private static String getMergedStringUsingJava7(List<String> strings, String separator) {
     StringBuilder stringBuilder = new StringBuilder();
   	
     for(String string: strings) {
   	
        if(!string.isEmpty()) {
           stringBuilder.append(string);
           stringBuilder.append(separator);
        }
     }
     String mergedString = stringBuilder.toString();
     return mergedString.substring(0, mergedString.length()-2);
  }
   
  private static List<Integer> getSquares(List<Integer> numbers) {
     List<Integer> squaresList = new ArrayList<Integer>();
   	
     for(Integer number: numbers) {
        Integer square = new Integer(number.intValue() * number.intValue());
   		
        if(!squaresList.contains(square)) {
           squaresList.add(square);
        }
     }
     return squaresList;
  }
   
  private static int getMax(List<Integer> numbers) {
     int max = numbers.get(0);
   	
     for(int i = 1;i < numbers.size();i++) {
   	
        Integer number = numbers.get(i);
   		
        if(number.intValue() > max) {
           max = number.intValue();
        }
     }
     return max;
  }
   
  private static int getMin(List<Integer> numbers) {
     int min = numbers.get(0);
   	
     for(int i= 1;i < numbers.size();i++) {
        Integer number = numbers.get(i);
   	
        if(number.intValue() < min) {
           min = number.intValue();
        }
     }
     return min;
  }
   
  private static int getSum(List numbers) {
     int sum = (int)(numbers.get(0));
   	
     for(int i = 1;i < numbers.size();i++) {
        sum += (int)numbers.get(i);
     }
     return sum;
  }
   
  private static int getAverage(List<Integer> numbers) {
     return getSum(numbers) / numbers.size();
  }
}

结果:

Using Java 7:
List: [abc, , bc, efg, abcd, , jkl]
Empty Strings: 2
Strings of length 3: 3
Filtered List: [abc, bc, efg, abcd, jkl]
Merged String: abc, bc, efg, abcd, jkl
Squares List: [9, 4, 49, 25]
List: [1, 2, 13, 4, 15, 6, 17, 8, 19]
Highest number in List : 19
Lowest number in List : 1
Sum of all numbers : 85
Average of all numbers : 9
Random Numbers:
-1279735475
903418352
-1133928044
-1571118911
628530462
18407523
-881538250
-718932165
270259229
421676854
Using Java 8:
List: [abc, , bc, efg, abcd, , jkl]
Empty Strings: 2
Strings of length 3: 3
Filtered List: [abc, bc, efg, abcd, jkl]
Merged String: abc, bc, efg, abcd, jkl
Squares List: [9, 4, 49, 25]
List: [1, 2, 13, 4, 15, 6, 17, 8, 19]
Highest number in List : 19
Lowest number in List : 1
Sum of all numbers : 85
Average of all numbers : 9.444444444444445
Random Numbers:
-1009474951
-551240647
-2484714
181614550
933444268
1227850416
1579250773
1627454872
1683033687
1798939493
Empty Strings: 2

原文来自:https://www.tutorialspoint.com/java8/java8_streams.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值