java.util.stream 是 Java 8 引入的新内容,提供以函数式的风格对流数据进行操作。
简单示例:
public static void fileStream(Collection<File> files) {
Predicate<File> predicate = new Predicate<File>() {
@Override
public boolean test(File file) {
return file.getName().endsWith(".exe");
}
};
Function<File, String> function = new Function<File, String>() {
@Override
public String apply(File file) {
return file.getName();
}
};
String resultStr = files.stream().filter(predicate).map(function).collect(Collectors.joining("; "));
System.out.println(resultStr);
}
可以通过以下几种常用方式来获取 Stram 对象:
(1) Collection.stream() 或 Collection.parallelStream() 方法;
(2) Arrays.stream(Object[]) 方法;
(3) Stream.of(Object[]),IntStream.range(int, int) 等静态工厂方法;
(4) Random.ints() 方法;
(5) BufferedReader.lines() 方法;
(6) Files 类中的某些方法;
(7) JDK中其它的流方法(很多)。
以 Stream<T> 为例,简单介绍一些常用方法。
(1) filter(Predicate<? super T> predicate):
返回一个 Stream,其中的元素都符合给定的条件,即根据指定条件过滤 Stream 元素。
对于 Stream 中的每一个元素,都会调用 predicate.text 方法,并将自身作为参数传递,若 text 返回 true,则表示该元素通过(被保留)。
若 text 方法中的逻辑比较简单,可以简化代码,示例如下:
// 格式:元素变量名 -> 条件(Boolean类型)
// 以 .exe 结尾的文件将被保留
filter(file -> file.getName().endsWith(".exe"))
(2) map(Function<? super T, ? extends R> mapper):
返回一个 Stream,其中的元素都已经按照指定方法处理,从 T 类型转至 R 类型。
对于 Stream 中的每一个元素,都会调用 mapper.apply 方法,并将自身作为参数传递,最终转化为目标类型数据并返回。
若 apply 方法中的逻辑比较简单,可以简化代码,示例如下:
// 格式:元素类型::调用方法名
// 每个元素调用 getName 方法,将得到的名称(String类型)作为元素放入返回的 Stream 中。
map(File::getName)
(3) sorted() / sorted(Comparator<? super T> comparator):
返回一个 Stream,其中的元素已经按照默认规则或指定规则进行排序。
(4) forEach(Consumer<? super T> action):
对于每一个元素,执行指定的操作。该方法属于终点操作。
(5) count():
返回 Stream 中的元素数量。该方法属于终点操作。
(6) toArray():
返回一个 Object 数组。该方法属于终点操作。
(7) collect(Collector<? super T,A,R> collector):
通过指定的操作,将 Stream 中的元素合并。该方法属于终点操作。
// 格式:合并操作
// 将 Stream 元素以分号为分隔进行合并
collect(Collectors.joining("; "))
终点操作(Terminal Operation):执行终点操作后,相应的 Stream 对象将被消耗,即该 Stream 对象不再可用。