JavaRush /Java 博客 /Random-ZH /流媒体接口

流媒体接口

已在 Random-ZH 群组中发布
流 API - 1

什么是流 API?

Stream API 是一种以函数式风格处理数据结构的新方法。Stream API(一个计算机程序与另一个程序通信的方式的描述)的核心是数据流。一般来说,“线程”这个术语本身在编程中,特别是在 Java 中是相当模糊的。
流 API - 1
随着 Java 8 的出现,Stream API 允许程序员编写更简短的代码,即简化数据集的处理,特别是简化过滤、排序和其他数据操作操作。如果没有中间操作,则可以而且应该经常不使用流,否则代码会比不使用流更复杂。
流 API - 2
我到底应该从哪里开始呢?从创建一个 Stream 实例开始,该实例基于我们需要的集合、数组或方法以及相应的数据来源:
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 的可能方法:
流 API - 3
  • 空流:Stream.empty()
  • 来自列表的流:list.stream()
  • 从地图流:map.entrySet().stream()
  • 来自数组的流:Arrays.stream(array)
  • 来自指定元素的流:Stream.of("1", "2", "3")
接下来是运算符(本质上是 Stream 类的方法),运算符可以分为两类:
  • 中间(也称为“惰性”)- 处理传入元素并返回流。元素处理链中可以有许多中间操作符。
  • 终端(“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))它依次遍历传递给它的集合的所有元素并显示它)
流 API - 5
要点:
  • 在呼叫终端操作员之前,处理不会开始。list.stream().filter(s -> s > 5)(不会从列表中取出单个元素);
  • 流的实例不能多次使用 =( ;
  • 流 API - 6

    因此,每次新的时候:

    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));
接下来,我们看一些中间运算符:
流 API - 7
  • filter(Predicate predicate)过滤流,仅传递那些通过条件的元素(Predicate 是 Java SE 8 中添加到包中的内置函数接口。检查“ true ”和“ falsejava.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(函数映射器)
另一个比较的例子,flatMap:
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
码头运营商:
流 API - 8
  • 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和流的第一个元素,应用函数accumulatoridentity成为它的结果。然后剩下的元素一切继续。

    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 并计算总和的收集器。

有用的链接: PS:不要羞于给我们点赞^ : ^
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION