Java学习笔记(五十八)—— Stream流

  • 传统的方式过滤集合

    		// 以传统的方式过滤集合
            List<String> list=new ArrayList<>();
            list.add("张三");
            list.add("张无忌");
            list.add("赵六");
            list.add("王五");
    
            List<String> lista=new ArrayList<>();
            for (String s : list) {
                if(s.startsWith("张")){
                    lista.add(s);
                }
            }
            List<String> listb=new ArrayList<>();
            for (String s : lista) {
                if(s.length()==3){
                    listb.add(s);
                }
            }
            System.out.println(list); // [张三, 张无忌, 赵六, 王五]
            System.out.println(lista); // [张三, 张无忌]
            System.out.println(listb); // [张无忌]
    
    
  • Stream流对集合进行过滤

    	List<String> list=new ArrayList<>();
        list.add("张三");
        list.add("张无忌");
        list.add("赵六");
        list.add("王五");
    	// Stream流对集合进行过滤
        list.stream().filter(name->name.startsWith("张"))
                        .filter(name->name.length()==3)
                        .forEach(name-> System.out.println(name)); // 张无忌
        System.out.println(list); // [张三, 张无忌, 赵六, 王五]
    
获取流
  • 所有的Collection集合都可以通过stream默认方法获取流

    default Stream<E> stream​() 返回一个序列 Stream与此集合作为其来源。 
    
        // 将集合转换为Stream流
        List<String> list = new ArrayList<>();
        Stream<String> streamList = list.stream();
    
        HashSet<String> setHash = new HashSet<>();
        Stream<String> streamSet = setHash.stream();
    
        HashMap<String, String> map = new HashMap<>();
        // 获取键存储到set集合中
        Set<String> keySet = map.keySet();
        Stream<String> streamMapKey = keySet.stream();
        // 获取值存储到Collection集合中
        Collection<String> values = map.values();
        Stream<String> streamMapValues = values.stream();
        // 获取键值对
        Set<Map.Entry<String, String>> entrySet = map.entrySet();
        Stream<Map.Entry<String, String>> streamMapEntry = entrySet.stream();
    
  • Stream接口的静态方法of可以获取数组对应的流

    static <T> Stream<T> of​(T... values) 返回其元素是指定值的顺序排序流。 
    
        // 数组转换为Stream流
        Stream<Integer> streamInteger = Stream.of(1, 2, 3, 5, 8);
        Integer[] arrInt={1,2,3,4};
        Stream<Integer> streamInteger1 = Stream.of(arrInt);
        String[] arrStr={"hello","world"};
        Stream<String> streamStr = Stream.of(arrStr);
    
常用方法
  • 延迟方法:返回值类型依然是Stream接口自身类型的方法,支持链式调用。(除终结方法外均为延迟方法)

    • filter方法,过滤剩下满足条件的元素组成新的流
    Stream<T> filter​(Predicate<? super T> predicate) 
    	返回由与此给定谓词匹配的此流的元素组成的流。  
    
        Stream<String> stream1 = Stream.of("张三丰", "张无忌", "赵敏", "周芷若");
        stream1.filter((item)->{
            return item.startsWith("张");
        }).forEach(item-> System.out.println(item)); // 张三丰,张无忌
    
    • map方法(映射)
    <R> Stream<R> map​(Function<? super T,? extends R> mapper) 返回由给定函数应用于此流的元素的结果组成的流。  
    
        Stream<String> stream2 = Stream.of("1", "2", "3", "4");
        stream2.map((item)->{
            return Integer.parseInt(item)+1;
        }).forEach((item)->{
            System.out.println(item); // 2,3,4,5
        });
    
    • limit方法,对流进行截取,只取前n个
    Stream<T> limit​(long maxSize) 返回由此流的元素组成的流,截短长度不能超过 maxSize 。  
    
        Stream<String> stream4 = Stream.of("hello", "world", "nihao", "wohao", "dajiahao");
        stream4.limit(2).forEach((item)->{
            System.out.println(item); // hello,world
        });
    
    • skip方法,跳过前n个元素,获取新的流
    Stream<T> skip​(long n) 在丢弃流的第一个到n元素后,返回由该流的剩余元素组成的流。  
    
        Stream<Character> stream5 = Stream.of('a', 'b', 'c', 'd', 'e', 'f');
        stream5.skip(4).forEach((item)->{
            System.out.println(item); // e,f
        });  
    
    • coucat方法,两个流合并为一个流,属于静态方法
    static <T> Stream<T> concat​(Stream<? extends T> a, Stream<? extends T> b) 
    	创建一个懒惰连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。  
    
        Stream<String> stream6 = Stream.of("hello");
        Stream<String> stream7 = Stream.of("nihao");
        Stream.concat(stream6,stream7).forEach((item)->{
            System.out.println(item);
        });
    
  • 终结方法:返回值类型不是Stream接口自身类型的方法,不支持链式调用。(count和forEach方法)

    • forEach方法,用来遍历流中的数据
    void forEach​(Consumer<? super T> action) 
    	对此流的每个元素执行操作。  
    
        Stream<String> stream = Stream.of("zhangsan", "wangwu", "lisi");
        stream.forEach((item)->{
            System.out.println(item); // zhangsan,wangwu,lisi
        });
    
    • count方法,统计个数
    long count​() 返回此流中的元素数。  
    
        Stream<Integer> stream3 = Stream.of(1, 2, 3, 4, 5);
        long len=stream3.filter((item)->{
            return item>3;
        }).count();
        System.out.println(len); // 2
    
  • 特点

    • Stream属于管道流,只能被消费使用一次。
案例
  1. public class Person {
        private String name;
        private int age;
    
        public Person() {
        }
    
        public Person(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;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
        ArrayList<String> listOne = new ArrayList<>();
        listOne.add("欧阳飞雪");
        listOne.add("土豆");
        listOne.add("张无忌");
        listOne.add("张君宝");
        listOne.add("小熊");
        listOne.add("好事多");
    
        ArrayList<String> listTwo = new ArrayList<>();
        listTwo.add("古力娜扎");
        listTwo.add("狼牙");
        listTwo.add("迪丽热巴");
        listTwo.add("尼古拉斯凯奇");
        listTwo.add("张官司");
        listTwo.add("张无知");
        listTwo.add("张天佑");
        listTwo.add("张翠山");
    
    	// 只要第一个集合中长度等于3的前两个
        Stream<String> listOneResult = listOne.stream().filter((item) -> {
            return item.length() == 3;
        }).limit(2);
        // 只要第二个集合中以张开头的,不要前两个
        Stream<String> listTwoResult = listTwo.stream().filter((item) -> {
            return item.startsWith("张");
        }).skip(2);
        // 将两个流合并,并用里面的每一个元素来创建一个Person对象,存储到新的流中
        Stream.concat(listOneResult,listTwoResult).map((name)->{
            return new Person(name,new Random().nextInt(100));
        }).forEach(person -> {
            System.out.println(person);
        });
    
发布了113 篇原创文章 · 获赞 1 · 访问量 949

猜你喜欢

转载自blog.csdn.net/weixin_44876003/article/details/103379949