常用方法
Stream方法组合使用
第一种介绍字符串集合可进行的操作
import java.util.Arrays; import java.util.List; public class StreamExample { public static void main(String[] args) { List<String> list = Arrays.asList("apple", "banana", "cat", "dog", "egg"); long count = list.stream() // 创建Stream .filter(s -> s.length() == 3) // 过滤长度为3的元素 .map(String::toUpperCase) // 转换为大写 .sorted() // 排序 .count(); // 统计元素个数 System.out.println(count); // 输出:3 } }
上述代码中,首先创建了一个包含5个字符串的List,然后通过stream()方法将其转换为一个Stream。接着对Stream进行操作,包括过滤、转换为大写、排序和统计元素个数。最后将统计结果打印出来。
具体步骤和注释如下:
list.stream(): 将List转换为一个Stream对象。
filter(s -> s.length() == 3): 对Stream中的元素进行过滤,只保留长度为3的元素。
map(String::toUpperCase): 将Stream中的元素转换为大写。
sorted(): 对Stream中的元素进行排序。
count(): 统计Stream中元素的个数。
System.out.println(count): 将统计结果打印出来。
第二种介绍int类型集合可进行的操作
下面的代码演示了如何使用Stream的方法组合来完成以下三个操作:
找出所有大于5的偶数,并将结果存储到一个列表中;
计算列表中所有元素的平方和;
找出列表中的最大值和最小值。
import java.util.Arrays; import java.util.List; public class StreamDemo { public static void main(String[] args) { // 创建一个包含整数的列表 List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // 找出所有大于5的偶数,并将结果存储到一个列表中 List<Integer> result = numbers.stream() .filter(n -> n > 5) // 过滤出大于5的数 .filter(n -> n % 2 == 0) // 过滤出偶数 .collect(Collectors.toList()); // 将结果存储到一个列表中 System.out.println(result); // 计算列表中所有元素的平方和 int sum = numbers.stream() .mapToInt(n -> n * n) // 将元素映射为它的平方 .sum(); // 计算和 System.out.println(sum); // 找出列表中的最大值和最小值 IntSummaryStatistics stats = numbers.stream() .mapToInt((x) -> x) // 将Stream<Integer>转换为IntStream .summaryStatistics(); // 计算统计信息 System.out.println("最大值: " + stats.getMax()); System.out.println("最小值: " + stats.getMin()); } }
下面分别对这三个操作进行详细的解释:
操作1:找出所有大于5的偶数,并将结果存储到一个列表中
首先,使用filter()方法过滤出大于5的数,然后使用另一个filter()方法过滤出偶数,最后使用collect()方法将结果存储到一个列表中。
操作2:计算列表中所有元素的平方和
首先,使用mapToInt()方法将每个元素映射为它的平方,然后使用sum()方法计算和。
操作3:找出列表中的最大值和最小值
首先,使用mapToInt()方法将Stream转换为IntStream,然后使用summaryStatistics()方法计算统计信息,包括最大值和最小值。
第三种介绍collect()和filter()组合的使用方式
在下面的代码中,首先创建了一个包含数字1到10的List。然后,调用stream()方法将List转换为一个Stream。接着,调用filter()方法对Stream中的元素进行过滤操作,只保留偶数元素。最后,调用collect()方法将结果收集到一个新的List中。
import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class StreamDemo { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); List<Integer> result = numbers.stream() .filter(number -> number % 2 == 0) .collect(Collectors.toList()); System.out.println(result); } }
将一个包含学生信息的List转换为一个以学生名字为键,学生对象为值的Map。
在下面的代码中,首先创建了一个包含三个学生信息的List。然后,调用stream()方法将List转换为一个Stream。接着,调用collect()方法,并传递一个Collectors.toMap()方法作为参数。在toMap()方法中,使用Student::getName将学生名字作为Map的键,使用student -> student将学生对象作为Map的值。最终,将结果存储到一个Map对象中。
import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class StreamDemo { public static void main(String[] args) { List<Student> students = Arrays.asList( new Student("Tom", 18), new Student("Jack", 20), new Student("Lucy", 19) ); Map<String, Student> result = students.stream() .collect(Collectors.toMap(Student::getName, student -> student)); System.out.println(result); } } class Student { private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
方法对比flatMap()和filter()
这两个方法都可以用来筛选流中的数据,但它们的实现方式和作用是不同的。
flatMap()方法的作用是将一个Stream中的每个元素都转换为一个新的流,然后将这些流合并成一个新的流。换句话说,flatMap()方法用来处理嵌套的流结构,并将它们扁平化为一个单一的流。因此,flatMap()方法常用于将嵌套的集合或数组展开为一个单独的流,以方便进一步的处理。
下面是一个使用flatMap()方法的示例代码:
/
List<List<Integer>> numbers = Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3, 4), Arrays.asList(5, 6)); List<Integer> flattenedNumbers = numbers.stream() .flatMap(Collection::stream) .collect(Collectors.toList()); System.out.println(flattenedNumbers); // Output: [1, 2, 3, 4, 5, 6]
在上面的代码中,首先创建了一个包含多个集合的列表numbers。然后,调用stream()方法将这个列表转换为一个Stream。接着,使用flatMap()方法将每个集合都转换为一个新的流,并将这些流合并为一个新的流。最后,使用collect()方法将所有的元素收集到一个新的List中。
filter()方法的作用是根据指定的条件筛选出符合条件的元素,并将它们收集到一个新的Stream中。换句话说,filter()方法用于对Stream中的元素进行条件过滤。因此,filter()方法常用于从一个大的数据集合中,选择符合条件的元素,以用于进一步的处理。
下面是一个使用filter()方法的示例代码:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList()); System.out.println(evenNumbers); // Output: [2, 4, 6]
在上面的代码中,首先创建了一个包含多个整数的列表numbers。然后,调用stream()方法将这个列表转换为一个Stream。接着,使用filter()方法过滤出所有偶数,并将它们收集到一个新的Stream中。最后,使用collect()方法将所有偶数收集到一个新的List中。
需要注意的是,flatMap()和filter()方法都是用于处理Stream中的数据,并返回一个新的Stream,它们常常被用于组合使用,以达到对数据进行更复杂处理的目的。
Stream的创建
可以通过以下方式创建Stream:
1. 从集合或数组创建
可以通过Collection.stream()或Arrays.stream()方法来创建Stream。
List<String> list = Arrays.asList("a", "b", "c"); Stream<String> stream = list.stream();
2. 使用Stream.of()创建
使用Stream.of()方法创建一个Stream。
Stream<String> stream = Stream.of("a", "b", "c"); 1
3. 使用Stream.iterate()创建
使用Stream.iterate()方法创建一个无限流。
Stream<Integer> stream = Stream.iterate(0, n -> n + 2);
4. 使用Stream.generate()创建
使用Stream.generate()方法创建一个无限流。
Stream<Double> stream = Stream.generate(Math::random);
Stream的中间操作
中间操作是指对数据源进行处理并返回一个Stream对象的操作,可以对数据源进行筛选、映射、去重、排序等操作。
以下是常用的Stream中间操作:
1. filter
该方法用于通过设置的条件过滤出元素,返回一个新的Stream对象。
Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); stream.filter(s -> s.length() > 5).forEach(System.out::println);
2. map
该方法用于将元素按照某种规则进行转换,返回一个新的Stream对象。
Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); stream.map(String::toUpperCase).forEach(System.out::println);
3. flatMap
该方法用于将一个Stream中的每个元素转换为另一个Stream,然后将所有Stream中的元素合并成一个Stream,返回一个新的Stream对象。
具体来说,flatMap()方法接收一个函数作为参数,这个函数将一个元素转换为一个新的流。然后,flatMap()方法将所有这些新的流合并成一个新的流,最后返回这个新的流。如果这个函数返回的是一个空的流,那么这个流中就不会包含任何元素。
Stream<List<Integer>> stream = Stream.of(Arrays.asList(1, 2), Arrays.asList(3, 4)); stream.flatMap(Collection::stream).forEach(System.out::println);
4. distinct
该方法用于对Stream中的元素进行去重,返回一个新的Stream对象。
Stream<String> stream = Stream.of("apple", "banana", "orange", "apple"); stream.distinct().forEach(System.out::println);
5. sorted
该方法用于对Stream中的元素进行排序,返回一个新的Stream对象。
Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); stream.sorted().forEach(System.out::println);
6. peek
该方法用于在执行Stream中的下一个操作时对元素进行操作,返回一个新的Stream对象。
Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); stream.peek(s -> System.out.println("before filter: " + s)).filter(s -> s.length() > 5) .peek(s -> System.out.println("after filter: " + s)).forEach(System.out::println);
7. limit
该方法用于截取Stream中前n个元素,返回一个新的Stream对象。
Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); stream.limit(2).forEach(System.out::println);
8. skip
该方法用于跳过Stream中前n个元素,返回一个新的Stream对象。
Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); stream.skip(2).forEach(System.out::println);
9. parallel
该方法用于将Stream转换为并行流,返回一个新的Stream对象。
Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); stream.parallel().forEach(System.out::println);
10. sequential
该方法用于将Stream转换为串行流,返回一个新的Stream对象。
Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); stream.parallel().sequential().forEach(System.out::println);
Stream的终止操作
终止操作是指对Stream进行最终操作,产生一个结果或副作用,但不再返回Stream对象。
以下是常用的Stream终止操作:
1. forEach
该方法用于对Stream中的元素进行遍历操作。
Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); stream.forEach(System.out::println);
2. toArray
该方法用于将Stream中的元素转换为数组。
Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); String[] strArr = stream.toArray(String[]::new);
3. reduce
该方法用于将Stream中的所有元素按照指定的规则进行归约操作,返回一个Optional对象。
Stream<Integer> stream = Stream.of(1, 2, 3, 4); Optional<Integer> result = stream.reduce((x, y) -> x + y); result.ifPresent(System.out::println);
4. collect
该方法用于将Stream中的元素收集到一个集合中,返回一个新的集合对象。
Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); List<String> list = stream.collect(Collectors.toList());
5. count
该方法用于计算Stream中的元素个数,返回一个long类型的值。
Stream<String> stream = Stream.of("apple", "banana", "orange", "pear"); long count = stream.count(); System.out.println(count);
6. anyMatch
该方法用于判断Stream中是否存在满足指定条件的元素,返回一个boolean类型的值。
Stream<Integer> stream = Stream.of(1, 2, 3, 4); boolean result = stream.anyMatch(x -> x > 2); System.out.println(result);
7. allMatch
该方法用于判断Stream中的所有元素是否都满足指定条件,返回一个boolean类型的值。
Stream<Integer> stream = Stream.of(1, 2, 3, 4); boolean result = stream.allMatch(x -> x > 0); System.out.println(result);
8. noneMatch
该方法用于判断Stream中的所有元素是否都不满足指定条件,返回一个boolean类型的值。
Stream<Integer> stream = Stream.of(1, 2, 3, 4); boolean result = stream.noneMatch(x -> x > 5); System.out.println(result);
9. findAny
该方法用于获取Stream中的任意一个元素,返回一个Optional对象。
Stream<Integer> stream = Stream.of(1, 2, 3, 4); Optional<Integer> result = stream.findAny(); result.ifPresent(System.out::println);
10. findFirst
该方法用于获取Stream中的第一个元素,返回一个Optional对象。
Stream<Integer> stream = Stream.of(1, 2, 3, 4); Optional<Integer> result = stream.findFirst(); result.ifPresent(System.out::println);