Java 8中流Stream API详解

发布时间:2023年12月28日

先给个示例,展示Java 8流API的优势

假设我们有以下任务:

给定一个字符串列表,我们需要执行以下操作:

  1. 筛选出所有以"A"开头的字符串。

  2. 将这些字符串转换为大写。

  3. 对这些字符串按照长度进行排序。

  4. 最后,将这些字符串连接成一个以逗号分隔的单个字符串。

    Java 7及之前的实现:

    在Java 7中,实现这一功能需要多步骤处理,涉及到循环、条件判断、排序和字符串拼接等多个环节。

    List<String> inputList = Arrays.asList("Apple", "An", "Banana", "Avocado", "Apricot", "Blueberry");
    List<String> filteredList = new ArrayList<String>();
    for (String s : inputList) {
        if (s.startsWith("A")) {
            filteredList.add(s.toUpperCase());
        }
    }
    Collections.sort(filteredList, new Comparator<String>() {
        public int compare(String s1, String s2) {
            return Integer.compare(s1.length(), s2.length());
        }
    });
    
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < filteredList.size(); i++) {
        sb.append(filteredList.get(i));
        if (i < filteredList.size() - 1) {
            sb.append(", ");
        }
    }
    String result = sb.toString();
    

    Java 8使用流的实现:

    相同的任务可以使用Java 8的流API以更简洁、更直观的方式实现:

    List<String> inputList = Arrays.asList("Apple", "An", "Banana", "Avocado", "Apricot", "Blueberry");
    String result = inputList.stream()
                             .filter(s -> s.startsWith("A"))
                             .map(String::toUpperCase)
                             .sorted(Comparator.comparingInt(String::length))
                             .collect(Collectors.joining(", "));
    

    对比

    在Java 7的实现中,我们需要显式地进行循环、条件判断、排序和字符串拼接,这不仅使代码变得更长,也使得逻辑更难以一眼看明。而在Java 8的实现中,所有这些操作都被整合进了一个流水线式的链式调用中,每个步骤都清晰、直观。filtermapsortedcollect等方法的使用使得代码更易读和维护。特别是使用Collectors.joining直接将筛选和转换后的字符串列表拼接成一个字符串,大大简化了代码。这个例子清楚地展示了Java 8流API的强大能力,特别是在处理复杂的集合操作时,其优势是非常明显的。

一、什么是流Stream?

Java 8的流Stream是对集合对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作(bulk data operation)。Stream API可以极大提高Java程序员的生产力,让程序员写出高效、干净、简洁的代码。

Java 8的Stream API提供了一种高效、声明式处理集合的方法。使用Stream API,你可以对集合执行复杂的查询、过滤、转换、排序等操作,而无需关心底层的实现细节。

二、为什么要用流?

Java 8引入了流(Stream)是为了更方便、更灵活地处理集合数据。流提供了一种新的抽象,让开发者能够以声明性的方式对数据进行操作,而不再需要显式地使用迭代器或写大量的循环代码。

三、不用流会怎样?

虽然不使用流仍然可以实现相同的功能,但使用流可以提供更简洁、更高效、更易于维护的代码,尤其是在处理复杂的数据操作时。流API是Java 8中的一个重要特性,它极大地改善了Java语言在处理集合方面的能力。

四、流Stream有啥特点

  • 不是数据结构:它不存储数据,只是用来操作数据源(如集合、数组等)中的数据。
  • 不改变原对象:它不会修改原对象,相反,它会返回一个持有结果的新Stream。
  • 惰性执行:操作是延迟执行的,这意味着它们会等到需要结果的时候才执行。
  • 可消费性:Stream只能被消费一次。一旦遍历过就会失效。

五、流的常用方法?

Stream操作分为两种:中间操作和终端操作。

中间操作
  • map (映射):将元素转换成其他形式或提取信息。

    stream.map(String::toUpperCase);
    
  • filter (过滤):排除某些元素。

    stream.filter(e -> e.length() > 2);
    
  • sorted (排序):确保流按照某种准则排序。

    stream.sorted(Comparator.comparingInt(String::length));
    
  • limit (限制):减少流的大小。

    stream.limit(5);
    
  • distinct (去重):通过流所生成元素的 hashCode() 和 equals() 去除重复元素。

    stream.distinct();
    
终端操作
  • forEach (迭代):迭代流中的每个数据。

    stream.forEach(System.out::println);
    
  • collect (收集):将流转换为其他形式。

    List<String> list = stream.collect(Collectors.toList());
    
  • reduce (归约):将流中的所有元素重复结合起来,得到一个值。

    Integer sum = numbers.stream().reduce(0, Integer::sum);
    
  • anyMatch、allMatch、noneMatch (匹配):检查流中是否有一个或多个元素匹配给定的谓词。

    boolean anyMatch = stream.anyMatch(e -> e.startsWith("A"));
    
  • count (计数):返回流中元素的个数。

    long count = stream.count();
    
  • findFirst、findAny (查找):返回流中的第一个或任意一个元素。

    Optional<String> first = stream.findFirst();
    

六、示例

List<String> myList = Arrays.asList("a1", "a2", "b1", "c2", "c1");

myList.stream()
    .filter(s -> s.startsWith("c"))
    .map(String::toUpperCase)
    .sorted()
    .forEach(System.out::println); // C1, C2

在此示例中,stream() 创建了一个流,filter() 方法过滤掉非 “c” 开头的字符串,map() 方法将每个字符串转换为大写,sorted() 方法对字符串进行排序,最后 forEach() 方法打印每个元素。

文章来源:https://blog.csdn.net/wykqh/article/details/135142869
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。