Java笔记 -Stream流

Stream流

用来简化集合或者数组操作,JDK8 的新特性,需要结合 Lambda 表达式一起用
Stream 流不是一个集合
Stream 流是一个集合元素的函数模型
Stream 流本身不存储任何元素或者地址值

概述、特点

  • 使用 Stream流 可以将以前多步操作的代码,用一步代码就写完了(链式 流式)
  • 使用 Stream流 对元素进行操作编程思想: 把元素的操作比喻为流水线上加工的产品,在流水线有不同的加工环节,层层加工之后,最后出厂
  • 在数据流中,是不能修改原集合数据的
  • Stream流 只能使用一次

步骤

  1. 创建一条生产线,并且把加工的产品准备好(创建 Stream流,准备好操作的元素)
  2. 在流水线上对产品进行层层加工(Stream流 提供的中间操作方法)
  3. 产品加工完下线(Stream流 提供的终结方法)

获取Stream流

  • 集合名.stream().forEach,获取集合的流
  • Stream 接口的静态方法 .of 可以获取数组对应的流
  • Map keySet(): 获取键集合 values(): 获取值集合
    例:
HashMap<String, Integer> hm = new HashMap<>();

hm.put("Test1", 1);
hm.put("Test2", 2);
hm.put("Test3", 3);
hm.put("Test4", 4);
hm.put("Test5", 5);

Collection<Integer> values = hm.values();
values.stream().forEach(i -> {
    System.out.println(i);
});

Stream中间方法

Stream 中间方法的特点: 调用完方法后,返回的还是一个 Stream 流,所以可以继续调用 Stream 流的方法

filter

将指定元素过滤出来

例:

List<String> list = new ArrayList<>();

list.add("Test1");
list.add("Test2");
list.add("Test3");
list.add("Test4");
list.add("Test5");

list.stream().filter(new Predicate<String>() {
    @Override
    public boolean test(String s) {
        return "Test2".equals(s);
    }
}).forEach(s -> System.out.println(s));

list.stream().filter(s -> "Test3".equals(s))
        .forEach(s -> System.out.println(s));

limit

限制遍历个数

例:

ArrayList<String> list = new ArrayList<>();

list.add("Test1");
list.add("Test2");
list.add("Test1");
list.add("Test3");
list.add("Test4");
list.add("Test5");
list.add("Test6");
list.add("Test7");
list.add("Test8");
list.add("Test6");

list.stream().limit(4).forEach(s -> System.out.println(s));

skip

跳过某些元素

例:

ArrayList<String> list = new ArrayList<>();

list.add("Test1");
list.add("Test2");
list.add("Test1");
list.add("Test3");
list.add("Test4");
list.add("Test5");
list.add("Test6");
list.add("Test7");
list.add("Test8");
list.add("Test6");

list.stream().skip(4).forEach(s -> System.out.println(s));

distinct

去除重复元素

例:

ArrayList<String> list = new ArrayList<>();

list.add("Test1");
list.add("Test2");
list.add("Test1");
list.add("Test3");
list.add("Test4");
list.add("Test5");
list.add("Test6");
list.add("Test7");
list.add("Test8");
list.add("Test6");

list.stream().distinct().forEach(s -> System.out.println(s));

concat

合并两个流

例:

ArrayList<String> list = new ArrayList<>();
ArrayList<String> list1 = new ArrayList<>();

list.add("Test1");
list.add("Test2");
list.add("Test1");
list.add("Test3");
list.add("Test4");
list.add("Test5");
list.add("Test6");
list.add("Test7");
list.add("Test8");
list.add("Test6");

list1.add("T1");
list1.add("T2");

Stream.concat(list.stream(), list1.stream()).forEach(s -> System.out.println(s));

sorted

Steam 流中元素进行排序

ArrayList<String> list = new ArrayList<>();

list.add("Test1");
list.add("Test2");
list.add("Test1");
list.add("Test3");
list.add("Test4");
list.add("Test5");
list.add("Test6");
list.add("Test7");
list.add("Test8");
list.add("Test6");

list.stream().sorted().forEach(s -> System.out.println(s));

Stream流的终结方法

  • forEach
  • count(): 返回流中元素的个数

Stream流的搜集方法

返回值不是 Stream 流,所以不能进行链式编程

  • collect
    • Collectors.toList
    • Collectors.toSet
    • Collectors.toMap

例:

// 实体类
public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

// 测试类
public class StreamCollectTest {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();

        for (int i = 1; i <= 10; i++) {
            list.add(i);
        }

        list.add(10);
        list.add(10);
        list.add(10);
        list.add(10);
        list.add(10);

        List<Integer> collectList = list.stream().filter(i -> i % 2 == 0)
                .collect(Collectors.toList());

        Set<Integer> collectSet = list.stream().filter(i -> i % 2 == 0)
                .collect(Collectors.toSet());

        System.out.println(list);
        System.out.println(collectList);
        System.out.println(collectSet);

        ArrayList<Student> students = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            students.add(new Student("test" + i, i));
        }

        Map<String, Integer> collectMap = students.stream().filter(s -> s.getAge() <= 5)
                .collect(Collectors.toMap(
                        s -> s.getName(),
                        s -> s.getAge()
                ));

        collectMap.forEach((key, value) -> {
            System.out.println(key + "..." + value);
        });
    }
}

  • 以上述情况搜集 Map 时会如果出现键值重复会抛出异常,推荐使用以下方式:
List<Pair<String, Double>> pairArrayList = new ArrayList<>(3);
pairArrayList.add(new Pair<>("version", 12.10));
pairArrayList.add(new Pair<>("version", 12.19));
pairArrayList.add(new Pair<>("version", 6.28));

Map<String, Double> map = pairArrayList.stream().collect(
Collectors.toMap(Pair::getKey, Pair::getValue, (v1, v2) -> v2)
);

map.entrySet().stream().forEach(
e -> System.out.println(e.getKey() + "..." + e.getValue())
);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值