Java Stream流

什么是Stream流?

当我们有一个需求:

现在有一份名单{“李博”,“张伟”,“曾小贤”,“胡一菲”,“张无忌”},要求筛选出姓“张”的人,并且名字长度是3的,放到一个新的数组里面去

如果我们使用传统方法来写,可能是这样的

public class B {
    public static void main(String[] args) throws IOException {
        ArrayList<String> arr=new ArrayList<>();

        //{"李博","张伟","曾小贤","胡一菲","张无忌"}
        arr.add("李博");
        arr.add("张伟");
        arr.add("曾小贤");
        arr.add("胡一菲");
        arr.add("张无忌");

        ArrayList<String> lastarr=new ArrayList<>();
        for (String s : arr) {
            if(s.startsWith("张") && s.length()==3){
                lastarr.add(s);
            }
        }

        System.out.println(lastarr);
    }
}

我们只是过滤了两个条件,当我们需要过滤的东西多了之后,代码会越来越多,那有没有解决方案呢?答案是有的,那就是使用Stream流

public class B {
    public static void main(String[] args) throws IOException {
        ArrayList<String> arr=new ArrayList<>();

        //{"李博","张伟","曾小贤","胡一菲","张无忌"}
        arr.add("李博");
        arr.add("张伟");
        arr.add("曾小贤");
        arr.add("胡一菲");
        arr.add("张无忌");

        arr.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(System.out::println);
    }
}

Stream流分为三步

  • 获取流
  • 中间操作
  • 终结操作

首先我们获取到了一个Stream流,然后我们进行了过滤和输出,这个过滤和输出我们使用lamda表达式完成,实际上filter()方法需要的参数是一个predicate检索接口,而forEach()所需要的其实是一个Consumer消费接口接口。

如何获取流?

stream() − 为集合创建串行流。
parallelStream() − 为集合创建并行流。

Collection体系的集合直接使用Stream获取

List<String> arrayList=new ArrayList<>();
Set<String> set=new HashSet<>();

Stream<String> arrayListStream = arrayList.stream();
Stream<String> setStream = set.stream();

Map体系的集合不可以直接获取,需要间接获取

Map<String,Integer> map=new HashMap<>();
Stream<String> keysStream = map.keySet().stream();//键集合流
Stream<Integer> valuesStream = map.values().stream();//值集合流
Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();//键=值 集合流

数组则需要使用Stream.of()方法

String[] strarr={"hello","world","orange"};
Stream<String> strarrStream = Stream.of(strarr);
Stream<String> strarrStream = Stream.of("apple", "pear", "banana");

Stream流常用的中间操作

以下方法是对这个集合做操作

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

arr.add("libo");
arr.add("zhangwei");
arr.add("zhangwan");
arr.add("zengxiaoxian");
arr.add("huyifei");
arr.add("huyiwei");
arr.add("zhangweiji");

filter(Predicate predicate) 返回满足筛选条件的的数据的一个新的流,一般用于过滤

//filter
arr.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(System.out::println);
//我们这句就是过滤了不是姓张的,并且名字长度不等于3的人

limit(long maxSize) 截取流的一部分

//limit
//假如我们需要前三个元素
arr.stream().limit(3).forEach(System.out::println);

skip(long n) 跳过流的一部分,取流的剩余部分

//skip
//假如我们需要后脸两个元素
arr.stream().skip(3).forEach(System.out::println);

concat(Stream s1,Stream s2) 注意这是个静态方法。该方法用于连接两个流。

//concat
//前三个元素
Stream<Integer> sk1 = arr.stream().limit(3);

//后三个元素
Stream<Integer> sk2 = arr.stream().skip(2);

//合并两个流
Stream.concat(sk1, sk2).forEach(System.out::println);

distinct() 去掉重复元素

//distinct
//去掉重复的元素
concat.distinct().forEach(System.out::println);

sorted(Comparator comparator) 参数是可选的。如果不指定参数则进行自然排序,如果有参数,则根据比较器进行排序,需要注意的是自然排序是根据ASCll码来的

//sorted
//自然排序
arr.stream().sorted().forEach(System.out::println);
//比较器排序
arr.stream().sorted((s1,s2)->s1.length()-s2.length()).forEach(System.out::println);

map(Function function) 返回执行完操作过后的流,也就是对流中的元素做了操作之后返回一个新的流

//map
ArrayList<String> arr=new ArrayList<>();

arr.add("1");
arr.add("2");
arr.add("3");
arr.add("4");
//字符串转换成数值
arr.stream().map(Integer::parseInt).forEach(System.out::println);

mapToInt(ToIntFunction mapper) 能做的事情和map差不多,但是它返回的是一个int流,让我们可以使用IntegerStream中的方法,其他的还有一个mapToDouble(),mapToLong之类的

//mapToInt
ArrayList<String> arr=new ArrayList<>();

arr.add("1");
arr.add("2");
arr.add("3");
arr.add("4");
//使用了IntegerStream中的sum()方法来求和,需要注意的是sum()是一个终止操作
int result=arr.stream().mapToInt(Integer::parseInt).sum();
System.out.println(result);

count() 统计流中的元素个数

//count
long zhang = arr.stream().filter(s -> s.startsWith("zhang")).count();
System.out.println(zhang);

collect(Collector collector) 收集流信息。个人理解就是把流放到一个新集合。它通过Collector进行具体的收集(具体的可以去了解一下Collectors工具类,这里不细说)。

//collect
public class B {
    public static void main(String[] args) throws IOException {
        //toList
        ArrayList<String> arr=new ArrayList<>();


        arr.add("libo");
        arr.add("zhangwei");
        arr.add("zhangwan");
        arr.add("zengxiaoxian");
        arr.add("huyifei");
        arr.add("huyiwei");
        arr.add("zhangweiji");

        Stream<String> stringStream = arr.stream().filter(s -> s.length() == 8);
        Set<String> collect = stringStream.collect(Collectors.toSet());
        System.out.println(collect);

        //toSet()
        Set<Integer> set=new HashSet<>();

        set.add(23);
        set.add(30);
        set.add(25);
        set.add(22);
        set.add(50);

        Stream<Integer> integerStream = set.stream().filter(n -> n > 25);
        Set<Integer> filterSet = integerStream.collect(Collectors.toSet());

        //toMap
        String[] strarr={"吴彦祖,30","彭于晏,25","李波,20"};

        Map<String, Integer> collect1 = Stream.of(strarr).collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));
        Set<Map.Entry<String, Integer>> entries = collect1.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
            System.out.println(entry);
        }
    }
    
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值