Stream流—常用简单方法

说到Stream便容易想到I/O Stream,而实际上,谁规定“流”就一定是“IO流”呢?在Java 8中,得益于Lambda所带
来的函数式编程,引入了一个全新的Stream概念,用于解决已有集合类库既有的弊端。

循环遍历的弊端

Java 8的Lambda让我们可以更加专注于做什么(What),而不是怎么做(How),这点此前已经结合内部类进行
了对比说明。现在,我们仔细体会一下上例代码,可以发现

  1. for循环的语法就是“怎么做”
  2. for循环的循环体才是“做什么”

为什么使用循环?因为要进行遍历。但循环是遍历的唯一方式吗?遍历是指每一个元素逐一进行处理,而并不是从
第一个到最后一个顺次处理的循环。前者是目的,后者是方式。

每当我们需要对集合中的元素进行操作的时候,总是需要进行循环、循环、再循环。这是理所当然的么?不是。循
环是做事情的方式,而不是目的。另一方面,使用线性循环就意味着只能遍历一次。如果希望再次遍历,只能再使用另一个循环从头开始。

public class Main {

    public static void main(String[] args) {
//创建一个list集合储存姓名
        List<String> list=new ArrayList<>();
        list.add("小刘");
        list.add("小赵");
        list.add("小宝贝");
        list.add("老王");
        list.add("老王八");
        //过滤以“小”开头为的字符
        list.stream().filter(s->s.startsWith("小"))
                //过滤字符长度为3的
                .filter(s->s.length()==3)
                //遍历stream集合
                .forEach(s-> System.out.println(s));
    }
}
打印结果:小宝贝

直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤以"小"开头、过滤长度为3、逐一打印。代码
中并没有体现使用线性循环或是其他任何算法进行遍历,我们真正要做的事情内容被更好地体现在代码中。
stream的常用方法

  • 逐一处理:forEach
    虽然方法名字叫 forEach ,但是与for循环中的“for-each”昵称不同。
public class Main {

    public static void main(String[] args) {

       //获取一个stream流
         Stream<String> stream=Stream.of("小张","老王","小刘","小花");
        //使用stream流中的方法foreach对stream流中的数据进行遍历
        stream.forEach(s-> System.out.println(s));
打印结果:
小张
老王
小刘
小花
  • 过滤:filter
    可以通过 filter 方法将一个流转换成另一个子集流。
public class Main {

    public static void main(String[] args) {
//创建一个stream流
        Stream<String> stream = Stream.of("萧炎", "萧熏儿", "萧战", "药老", "美杜莎");
        //对stream流中的元素过滤,只要姓萧的人
        Stream<String> stream1 = stream.filter(s -> s.startsWith("萧"));
        //遍历stream1流
        stream1.forEach(s-> System.out.println(s));
    }
}
打印结果:
萧炎
萧熏儿
萧战

在这里通过Lambda表达式来指定了筛选的条件:必须姓张。

  • Stream流的特点:只能使用一次
    Stream流属于管道留,只能被消费(使用)一次,第一个Stream流调用完毕方法,数据就会流转到下一个Stream上,而这是第一个stream流已经使用完毕就会关闭。所以第一个stream流就不能调用方法了

  • 映射:map
    如果需要将流中的元素映射到另一个流中,可以使用 map 方法。

public class Main {

    public static void main(String[] args) {
//获取一个String类型的stream流
        Stream<String> stream = Stream.of("1", "2", "3", "4", "5");
        //使用map方法,把字符串类型的整数,转换(映射)成Integer类型的整数
        Stream<Integer> stream1= stream.map((String s) -> {
            return Integer.parseInt(s);});
        //遍历stream1
        stream1.forEach(s-> System.out.println(s));
    }
}
打印结果:
1
2
3
4
5

这段代码中, map 方法的参数通过方法引用,将字符串类型转换成为了int类型(并自动装箱为 Integer 类对象)。

  • 统计个数:count
    count用于统计Stream流中元素的个数
 long count();

count方法是一个终结方法,返回值是一个long类型的整数,所以不能继续调用Stream流中的其他方法

public class Main {

public static void main(String[] args) {

    List<String> list=new ArrayList<>();
    list.add("1");
    list.add("123");
    list.add("145");
    list.add("481");
    list.add("691");
    Stream<String> stream = list.stream();
    long count = stream.count();
    System.out.println(count);
    }
 }
打印结果:
5
  • 取用前几个:limit
    limit 方法可以对流进行截取,只取用前n个
public class Main {
    public static void main(String[] args) {
       // 获取stream流
        Stream<String> stream = Stream.of("张三", "李斯", "王五", "赵六", "田七");
        Stream<Stream<String>> stream1 = Stream.of(stream);
        //使用limit对Siream流中的元素进行截取,只要前三个元素
        Stream<String> stream2 = stream.limit(3);
        //遍历stream2
        stream2.forEach(s-> System.out.println(s));
        }
    }
打印结果:
张三
李斯
王五
  • 跳过前几个:skip
    如果希望跳过前几个元素,可以使用 skip 方法获取一个截取之后的新流
public class Main {
    public static void main(String[] args) {
      // 获取stream流
        Stream<String> stream = Stream.of("张三", "李斯", "王五", "赵六", "田七");
        Stream<Stream<String>> stream1 = Stream.of(stream);
        //使用skip方法,跳过前三个元素
        Stream<String> stream2 = stream.skip(3);
        //遍历
        stream2.forEach(s-> System.out.println(s));
        }
    }
打印结果:
赵六
田七
  • 组合:concat
    如果有两个流,希望合并成为一个流,那么可以使用 Stream 接口的静态方法 concat
public class Main {
    public static void main(String[] args) {
       // 获取stream流
        Stream<String> stream1 = Stream.of("张三", "李斯", "王五", "赵六", "田七");
        // 获取stream流
        Stream<String> stream2 = Stream.of("萧炎", "萧熏儿", "萧战", "药老", "美杜莎");
        //把两个流组合成一个流
        Stream<String> concat = Stream.concat(stream1, stream2);
        //遍历
        concat.forEach(s-> System.out.println(s));
        }
     }
打印结果:
张三
李斯
王五
赵六
田七
萧炎
萧熏儿
萧战
药老
美杜莎
### Java Stream API 常见用法及示例 #### 创建 可以通过多种方式创建 `Stream` ,最常用的是通过集合类的 `stream()` 方法。这使得能够轻松地将现有的集合转换成以便进一步处理。 ```java import java.util.Arrays; import java.util.List; public class CreateStreams { public static void main(String[] args) { List<String> names = Arrays.asList("Alice", "Bob", "Charlie"); // 使用集合的 stream() 方法创建 names.stream().forEach(System.out::println); } } ``` 此代码片段展示了如何利用 `List` 集合创建一个简单的字符串并打印其中每一个元素[^2]。 #### 过滤操作 过滤是常见的需求之一,在 `Stream` 中可通过调用 `filter(Predicate)` 来实现这一目的。该方法接收一个谓词作为参数,只有满足条件的数据项才会被保留下来继续参与后续的操作程。 ```java import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class FilterOperation { public static void main(String[] args) { List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); // 只选择偶数 List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .collect(Collectors.toList()); System.out.println(evenNumbers); // 输出 [2, 4, 6, 8] } } ``` 这段程序实现了筛选出给定整型列表里的所有偶数值[^1]。 #### 映射变换 映射是指对于输入序列中的每一项应用某个函数得到新的输出序列的过程;在 `Stream` 上执行此类操作通常会借助于 `map(Function)` 函数完成。它可以接受任意类型的对象并返回另一个类型的结果集合作为新产生的的一部分。 ```java import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class MapTransformation { public static void main(String[] args) { List<String> words = Arrays.asList("apple", "banana", "orange"); // 将单词转为大写形式 List<String> upperCaseWords = words.stream() .map(String::toUpperCase) .collect(Collectors.toList()); System.out.println(upperCaseWords); // 输出 [APPLE, BANANA, ORANGE] } } ``` 这里演示了怎样把一组字符串全部转化为它们的大写字母版本[^3]。 #### 归约汇总 当需要计算某些聚合统计量时(比如求和),可以采用终端操作 `reduce(BinaryOperator)` 或者更方便的方法如 `sum()`、`average()` 等来进行归约运算。这些方法能帮助快速获得整个数据集中特定属性的信息摘要。 ```java import java.util.Arrays; import java.util.List; public class ReductionOperations { public static void main(String[] args) { List<Integer> values = Arrays.asList(1, 2, 3, 4, 5); int sumOfValues = values.stream().reduce(0, Integer::sum); double averageValue = values.stream().mapToInt(val -> val).average().orElse(0.0); System.out.printf("Sum: %d\nAverage: %.2f%n", sumOfValues, averageValue); } } ``` 上述例子说明了两种不同的途径来获取一系列数字之和及其平均值[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值