什么是流 API?
Stream API 是一种以函数式风格处理数据结构的新方法。Stream API(一个计算机程序与另一个程序通信的方式的描述)的核心是数据流。一般来说,“线程”这个术语本身在编程中,特别是在 Java 中是相当模糊的。List<String> list = new ArrayList<String>();
list.add("One");
list.add("Two");
list.add("Three");
list.add("Four");
list.add("Five");
list.add("Six");
list.add("Seven");
list.add("Eight");
list.add("Nine");
list.add("Ten");
Stream stream = list.stream();
如上所述,Stream API 允许您减少代码行数。流的示例:
IntStream.of(50, 60, 70, 80, 90, 100, 110, 120).filter(x -> x < 90).map(x -> x + 10)
.limit(3).forEach(System.out::print);
没有线程的示例:
int[] arr = {50, 60, 70, 80, 90, 100, 110, 120
int count = 0;
for (int x : arr) {
if (x >= 90) continue;
x += 10;
count++;
if (count > 3) break;
System.out.print(x);
}
创建 Stream 的可能方法:
- 空流:
Stream.empty()
- 来自列表的流:
list.stream()
- 从地图流:
map.entrySet().stream()
- 来自数组的流:
Arrays.stream(array)
- 来自指定元素的流:
Stream.of("1", "2", "3")
- 中间(也称为“惰性”)- 处理传入元素并返回流。元素处理链中可以有许多中间操作符。
- 终端(“terminal”,也称为“eager”)——处理元素并终止流,因此链中只能有一个终端操作符。
1.List<String> list = new ArrayList<String>();
2.list.add("One");
…
11.list.add("Ten");
12.Stream stream = list.stream();
13.stream.filter(x-> x.toString().length() == 3).forEach(System.out::println);
这里发生了什么:
- 1 - 创建一个列表
list
; - 2-11-填写测试数据;
- 12-创建一个对象
Stream
; - 13 - 方法
filter
(过滤器) - 中间运算符,x
相当于枚举集合中的一个元素(与 一样for each
),之后 -> 我们指示如何过滤我们的集合,并且由于这是一个中间运算符,因此过滤后的集合进一步到方法,forEach
它又是枚举的终端(最终)类似物for each
(表达式System.out::println
缩写为:,x-> System.out.println(x))
它依次遍历传递给它的集合的所有元素并显示它)
- 在呼叫终端操作员之前,处理不会开始。
list.stream().filter(s -> s > 5)
(不会从列表中取出单个元素); - 流的实例不能多次使用 =( ;
因此,每次新的时候:
list.stream().filter(x-> x.toString().length() == 3).forEach(System.out::println);
list.stream().forEach(x -> System.out.println(x));
一个流上可以调用多个中间运算符,而只有一个终端运算符:
stream.filter(x-> x.toString().length() == 3).map(x -> x + " - the length of the letters is three").forEach(x -> System.out.println(x));
filter(Predicate predicate)
过滤流,仅传递那些通过条件的元素(Predicate 是 Java SE 8 中添加到包中的内置函数接口。检查“ true ”和“ false ”java.util.function
的值);map(Function mapper)
使得我们可以创建一个函数来更改每个元素并进一步跳过它(函数接口Function<T,R>
表示从 T 类型的对象到 R 类型的对象的转换函数)flatMap(Function<T, Stream<R>> mapper)
- 与 的情况一样map
,它们用于转换为原始流。
[stream1,stream2,stream3,stream4] => stream
:
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Convert the word to an array of letters
.flatMap(Arrays::stream).distinct() //aligns each generated thread into a single thread
.collect(Collectors.toList()).forEach(System.out::println);
当map
它转换为线程列表(更准确地说<Stream>
是线程)时[stream1,stream2,stream3,stream4] =>Stream.of(stream1,stream2,stream3,stream4)
:
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Convert the word to an array of letters
.map(Arrays::stream).distinct() //Make the array into a separate thread
.collect(Collectors.toList()).forEach(System.out::println);
与 相比的另一个区别是map
,您可以将一个元素转换为零、一个或多个其他元素。为了将一个元素转换为零个元素,您需要返回null
, 或一个空流。要转换为一个元素,您需要从一个元素返回一个流,例如 via Stream.of(x)
。要返回多个元素,您可以通过任何方式使用这些元素创建一个流。相同的 flatMap 方法,但对于 Double、Integer 和 Long:
- flatMapToDouble(函数映射器)
- flatMapToInt(函数映射器)
- flatMapToLong(函数映射器)
Stream.of(2, 3, 0, 1, 3)
.flatMapToInt(x -> IntStream.range(0, x))
.forEach(System.out::print);// 010120012
-
IntStream.range(0,x) – 将 0(含)到 x(不含)的元素输出到流;
地图:
Stream.of(2, 3, 0, 1, 3) .map(x -> IntStream.range(0, x)) .forEach(System.out::print);//list of streams (streams);
-
limit(long maxSize) – 按元素数量限制流:
stream.limit(5).forEach(x -> System.out.println(x));
-
Skip(long n) – 跳过 n 个元素:
stream.skip(3).forEach(x -> System.out.println(x));
-
排序()
- sorted(Comparator comparator) – 对流进行排序(像 TreeMap 一样排序):
stream.sorted().forEach(x -> System.out.println(x));
-
unique() — 检查流中元素的唯一性(删除元素的重复);
-
dropWhile(Predicate predicate) - 跳过满足条件的元素(出现在java 9中,Predicate<T>函数接口检查是否满足某个条件。如果满足,则返回true。lambda表达式接受一个对象输入 T 作为参数:
Predicate<Integer> isPositive = x -> x > 0; System.out.println(isPositive.test(3)); // true System.out.println(isPositive.test(-9)); // false
-
forEach(Consumer action) – 类似于 foreach(Consumer<T> 对类型 T 的对象执行某些操作而不返回任何内容);
-
count() – 返回流元素的数量:
System.out.println(stream.count());
-
collect(Collector Collector) – 方法将所有元素收集到列表、集合或其他集合中,根据某种标准对元素进行分组,将所有元素组合成字符串等:
List<String> list = Stream.of(“One”, “Two”, “Three”).collect(Collectors.toList());
-
collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)
— 与 相同,collect(collector)
只是为了方便而对参数进行了分解(supplier
提供新的对象(容器),例如new ArrayList()
,accumulator
向容器添加一个元素,combiner
将流的各个部分组合在一起); -
reduce(T Identity, BinaryOperator Accumulator) - 将流的所有元素转换为一个对象(计算所有元素的总和,或找到最小元素),首先取出该对象
identity
和流的第一个元素,应用函数accumulator
并identity
成为它的结果。然后剩下的元素一切继续。int sum = Stream.of(1, 2, 3, 4, 5).reduce(10, (acc, x) -> acc + x);// = 25
-
reduce(BinaryOperator accumulator)
— 与上面相同的方法,但缺少第一个元素identity
,它是流的第一个元素Optional min(Comparator comparator)
可选 max(Comparator comparator) 根据传入的比较器搜索最小/最大元素; -
findFirst()
– 取出流的第一个元素:Stream.of(1, 2, 3, 4, 9).findFirst();
-
allMatch(Predicate predicate)
—如果流的所有元素都满足条件,则返回true 。如果遇到调用谓词函数的结果为false 的任何元素,则运算符停止扫描元素并返回false:Stream.of(1, 2, 3, 4, 9).allMatch(x -> x <= 7);//false
-
anyMatch(Predicate predicate)
—如果流中至少有一个元素满足条件,则返回truepredicate
:Stream.of(1, 2, 3, 4, 9).anyMatch(x -> x >= 7);//true
-
noneMatch(Predicate predicate)
—如果遍历完流的所有元素后,没有一个元素满足条件,则返回truepredicate
:Stream.of(1, 2, 3, 4, 9).noneMatch(x -> x >= 7);//false
Collectors
:
-
toList()
— 将元素收集到List
:List<Integer> list = Stream.of(99, 2, 3).collect(Collectors.toList());
-
toSet()
— 将元素收集到一个集合中:Set<Integer> set = Stream.of(99, 2, 3).collect(Collectors.toSet());
-
counting()
— 计算元素数量:Long count = Stream.of("1", "2", "3", "4").collect(Collectors.counting());
-
joining()
-
joining(CharSequence delimiter)
-
joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)
— 将元素收集到一行中。此外,您可以指定分隔符以及整个序列的前缀和后缀:String a = Stream.of("s", "u" ,"p", "e", "r").collect(Collectors.joining()); System.out.println(a); // super String b = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining("-")); System.out.println(b); // s-u-p-e-r String c = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining(" -> ", "[ ", " ]")); System.out.println(c); // [ s -> u -> p -> e -> r ]
-
summingInt(ToIntFunction mapper)
-
summingLong(ToLongFunction mapper)
-
summingDouble(ToDoubleFunction mapper)
- 将对象转换为 int/long/double 并计算总和的收集器。
GO TO FULL VERSION