使用Java Stream API简化集合操作
今天我们将探讨如何使用Java Stream API来简化集合操作。Java 8引入了Stream API,它提供了一种高效且易读的方式来处理集合数据。通过使用Stream API,我们可以避免繁琐的循环和条件判断,使代码更加简洁和优雅。
1. 什么是Stream API
Stream API是一种用于处理集合的框架,它允许我们以声明性方式(就像SQL语句)处理数据。Stream操作可以分为中间操作和终端操作,其中中间操作返回一个新的Stream,允许操作链式调用,而终端操作会产生结果或者副作用。
2. 创建Stream
Stream可以从各种数据源创建,如集合、数组或I/O通道等。下面是一些常见的创建Stream的方式:
package cn.juwatech.stream; import java.util.Arrays; import java.util.List; import java.util.stream.Stream; public class StreamCreationExample { public static void main(String[] args) { // 从集合创建 List<String> list = Arrays.asList("a", "b", "c"); Stream<String> streamFromList = list.stream(); // 从数组创建 String[] array = {"a", "b", "c"}; Stream<String> streamFromArray = Arrays.stream(array); // 直接创建 Stream<String> streamDirect = Stream.of("a", "b", "c"); } }
3. 常见的中间操作
中间操作返回一个新的Stream,并且是惰性执行的。常见的中间操作包括filter、map、flatMap、sorted、distinct等。
3.1 filter
filter用于对Stream中的元素进行过滤,保留满足条件的元素。
package cn.juwatech.stream; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class StreamFilterExample { public static void main(String[] args) { 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); // 输出: [2, 4, 6] } }
3.2 map
map用于将Stream中的每个元素映射到另一个元素,通常用于元素类型的转换。
package cn.juwatech.stream; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class StreamMapExample { public static void main(String[] args) { List<String> words = Arrays.asList("hello", "world"); List<Integer> wordLengths = words.stream() .map(String::length) .collect(Collectors.toList()); System.out.println(wordLengths); // 输出: [5, 5] } }
3.3 flatMap
flatMap用于将每个元素转换成一个Stream,并将多个Stream合并成一个Stream。
package cn.juwatech.stream; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class StreamFlatMapExample { public static void main(String[] args) { List<List<String>> listOfLists = Arrays.asList( Arrays.asList("a", "b"), Arrays.asList("c", "d"), Arrays.asList("e", "f") ); List<String> flattenedList = listOfLists.stream() .flatMap(List::stream) .collect(Collectors.toList()); System.out.println(flattenedList); // 输出: [a, b, c, d, e, f] } }
3.4 sorted
sorted用于对Stream中的元素进行排序,默认是自然排序,也可以传入比较器进行自定义排序。
package cn.juwatech.stream; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class StreamSortedExample { public static void main(String[] args) { List<String> words = Arrays.asList("banana", "apple", "cherry"); List<String> sortedWords = words.stream() .sorted() .collect(Collectors.toList()); System.out.println(sortedWords); // 输出: [apple, banana, cherry] } }
3.5 distinct
distinct用于去重,返回由Stream中唯一元素组成的Stream。
package cn.juwatech.stream; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class StreamDistinctExample { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 3, 4, 4, 4, 4); List<Integer> distinctNumbers = numbers.stream() .distinct() .collect(Collectors.toList()); System.out.println(distinctNumbers); // 输出: [1, 2, 3, 4] } }
4. 常见的终端操作
终端操作会触发Stream的执行,并且会产生一个结果或副作用。常见的终端操作包括forEach、collect、reduce、count、anyMatch等。
4.1 forEach
forEach用于遍历Stream中的每个元素,并对其执行指定的操作。
package cn.juwatech.stream; import java.util.Arrays; import java.util.List; public class StreamForEachExample { public static void main(String[] args) { List<String> words = Arrays.asList("hello", "world"); words.stream().forEach(System.out::println); // 输出: // hello // world } }
4.2 collect
collect用于将Stream中的元素收集到一个集合或其他容器中。最常见的收集器是Collectors.toList()。
package cn.juwatech.stream; import java.util.Arrays; import java.util.List; import java.util.Set; import java.util.stream.Collectors; public class StreamCollectExample { public static void main(String[] args) { List<String> words = Arrays.asList("hello", "world", "hello"); Set<String> uniqueWords = words.stream() .collect(Collectors.toSet()); System.out.println(uniqueWords); // 输出: [world, hello] } }
4.3 reduce
reduce用于将Stream中的元素组合起来,生成一个单一的值。常见的操作有求和、求积、求最大值等。
package cn.juwatech.stream; import java.util.Arrays; import java.util.List; public class StreamReduceExample { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5); int sum = numbers.stream() .reduce(0, Integer::sum); System.out.println(sum); // 输出: 15 } }
4.4 count
count用于计算Stream中元素的个数。
package cn.juwatech.stream; import java.util.Arrays; import java.util.List; public class StreamCountExample { public static void main(String[] args) { List<String> words = Arrays.asList("hello", "world", "hello"); long count = words.stream().count(); System.out.println(count); // 输出: 3 } }
4.5 anyMatch
anyMatch用于判断Stream中是否至少有一个元素满足给定的条件。
package cn.juwatech.stream; import java.util.Arrays; import java.util.List; public class StreamAnyMatchExample { public static void main(String[] args) { List<String> words = Arrays.asList("hello", "world", "hello"); boolean hasHello = words.stream().anyMatch("hello"::equals); System.out.println(hasHello); // 输出: true } }
通过以上示例代码,我们可以看到Java Stream API如何简化集合操作,使代码更加简洁和易读。Stream API不仅提高了代码的可维护性,也让我们能更专注于业务逻辑的实现。