我是靠谱客的博主 阔达裙子,最近开发中收集的这篇文章主要介绍StreamAPI基本使用StreamAPI,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

StreamAPI

位于java.util.stream包下。

使用StreamAPI对集合数据进行操作,类似于使用SQL执行的数据库查询,并筛选需要的数据。

stream是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。

注意:

  • Stream自己不会存储元素
  • Stream不会改变原对象,相反,它们会返回一个持有结果的新Stream。
  • Stream操作是延迟执行的。

Stream的三个步骤

  1. 创建stream

    一个数据源(集合,数组等),获取一个流

  2. 中间操作

    一个中间操作,对数据源的数据进行处理

  3. 终止操作(终端操作)

    一旦执行终止操作,就执行中间操作链,产生结果,之后,不会再被使用。

Stream创建方式

1. 集合方式

@Test
public void test1(){
	List<String> list = Arrays.asList("2311", "jkll", "0988", "oppe", "uuuu");

	//default Stream<E> stream();返回顺序流
	Stream<String> stream = list.stream();//Collection接口中的stream()

	//default Stream<E> parallelStream();返回并行流
	Stream<String> parallelStream = list.parallelStream();
}

2. 数组方式

@Test
public void test2(){

        int[] arr = new int[]{1,4,2,3,4};
        //static <T> Stream<T> stream(T[] array)
        IntStream stream = Arrays.stream(arr);

        Person cul = new Person("Cul", 33);
        Person tim = new Person("Tim", 54);

        Person[] pArr = new Person[]{cul,tim};
        Stream<Person> personStream = Arrays.stream(pArr);
}

3. Stream.of()

@Test
public void test3(){
        Stream<String> stream = Stream.of("abc", "acb", "bac", "cab");
}

4. 创建无限流

@Test
public void test4(){
        //迭代
        // public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
        //seed为初始值
        Stream.iterate(0, t -> t + 2).limit(10);
        
        //生成
        //public static<T> Stream<T> generate(Supplier<T> s)
        Stream.generate(Math::random).limit(10);
}

Stream中间操作

中间操作不会执行任何的处理,而在终止操作时一次型全部处理,称为“惰性求值”。

1. 筛选与切片

方法描述
filter(Predicate p)接收lambda,从流中排除某些元素
distinct()筛选,通过流所生成元素的hashCode()和equals()去除重复元素
limit(long maxSize)截断流,使其元素不超过给定数量
skip(long n)跳过元素,返回一个扔掉了前n个元素的流,
若流中元素不足n个,则返回一个空流,与limit(n)互补
@Test
public void test1(){
        List<Person> list = getPersonList();
        //filter() 排除某些元素
        list.stream().filter(person -> person.getAge()<30).forEach(System.out::println);

        //limit() 截取前n个元素
        list.stream().limit(2).forEach(System.out::println);

        System.out.println("******");

        //skip(n) 跳过前n个元素
        list.stream().skip(2).forEach(System.out::println);

        //distinct() 根据hashCode和equals方法去重
        list.add(new Person("Tom",20));
        list.add(new Person("Tom",20));

        System.out.println("******");

        list.stream().distinct().forEach(System.out::println);
}

2. 映射

方法描述
map(Function f)接收一个函数作为参数,该函数会被应用到每个元素上,
并将其映射成一个新的元素
mapToDouble(ToDoubleFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,
产生一个新的DoubleStream
mapToInt(ToIntFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,
产生一个新的IntStream
mapToLong(ToLongFunction f)接收一个函数作为参数,该函数会被应用到每个元素上,
产生一个新的LongStream
flatMap(Function f)接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
@Test
public void test2(){
        //1.map(Function f)
        List<String> list = Arrays.asList("ad,az,df,ss,as,df");
        list.stream().map(str -> str.toUpperCase()).forEach(System.out::println);

        List<Double> list1 = Arrays.asList(30.0, 45.0, 90.0, 135.0, 180.0);
        list1.stream().map(Math::cos).forEach(System.out::println);

        //获取person name的length>3的name
        List<Person> personList = getPersonList();
        personList.stream().map(Person::getName).filter(name -> name.length() > 3).forEach(System.out::println);

        //2.flatMap(function f)类比list.add()和list.addAll()
        List<String> list2 = Arrays.asList("ad", "aa", "aj", "ak");
        list2.stream().flatMap(StreamMidOperate::trans).forEach(System.out::println);

}
public static Stream<Character> trans(String str){
        List<Character> list = new ArrayList<>();
        for (Character c : str.toCharArray()){
            list.add(c);
        }
        return list.stream();
}

3. 排序

方法描述
sorted()产生一个新流,其中按自然顺序排序
sorted(Comparator com)产生一个新流,其中按比较器顺序排序
@Test
public void test3(){
        //sorted() 自然排序
        List<Integer> list = Arrays.asList(2, 31, 4, 21, 9, 23, 45, 33);
        list.stream().sorted().forEach(System.out::println);

        //sorted(Comparator c) 自定义
        List<Person> personList = getPersonList();
    	personList.stream().sorted(Comparator.comparingInt(Person::getAge))
        .forEach(System.out::println);
}

Stream终止操作

流进行了终止操作后,不能再次使用

1. 匹配与查找

方法描述
allMatch(Predicate p)检查是否匹配所有元素
anyMatch(Predicate p)检查是否至少匹配一个元素
noneMatch(Predicate p)检查是否没有匹配所有元素
findFirst()返回第一个元素
findAny()返回当前流中的任意元素
count()返回流中元素总数
max(Comparator c)返回流中最大值
min(Comparator c)返回流中最小值
forEach(Consumer c)内部迭代
@Test
public void test1(){
        List<Person> list = getPerson();

        //allMatch(Predicate p) 是否所有的元素都满足条件
        //所有person的age是否都大于18
        boolean allMatch = list.stream().allMatch(p -> p.getAge() > 18);
        System.out.println(allMatch);

        //anyMatch(Predicate p) 是否有一个元素满足条件
        boolean anyMatch = list.stream().anyMatch(p -> p.getName().contains("a"));
        System.out.println(anyMatch);

        //noneMatch(Predicate p) 是否没有元素匹配
        boolean noneMatch = list.stream().noneMatch(p -> p.getName().length() > 6);
        System.out.println(noneMatch);

        //findFirst() 返回第一个元素
        Optional<Person> first = list.stream().findFirst();
        Person person = first.get();
        System.out.println(person);

        //findAny 返回任意元素
        Optional<Person> any = list.parallelStream().findAny();
        System.out.println(any);

}

@Test
public void test2(){

        List<Person> list = getPerson();

        //count()返回流中元素的总个数
        long count = list.stream().filter(p -> p.getAge() > 25).count();
        System.out.println(count);

        //max(Comparator c) 返回流中最大值
        Optional<Integer> max = list.stream().map(Person::getAge).max(Integer::compare);
        System.out.println(max);

        //min(Comparator c) 返回流中最小值
        Optional<Person> min = list.stream().min(Comparator.comparingInt(Person::getAge));
        System.out.println(min);

        //foreach() 内部迭代
        list.stream().forEach(System.out::println);
}

2. 归约

方法描述
reduce(T iden,BinaryOperator b)可以将流中元素反复结合起来,得到一个值,返回T
reduce(BinaryOperator b)可以将流中元素反复结合起来,得到一个值,返回Optional<T>
@Test
public void test3(){
        //reduce(T iden,BinaryOperator b)
        List<Integer> list = Arrays.asList(10,2,8,7,3,4,6);
        Integer sum = list.stream().reduce(0, Integer::sum);//identity为sum的基础值
        System.out.println(sum);

        List<Person> personList = getPerson();
        //reduce(BinaryOperator b)
        //Optional<String> reduce = personList.stream().map(Person::getId).reduce(String::concat);//获取所有id,并将id连接起来
        Optional<String> reduce = personList.stream().map(Person::getId).reduce((s1,s2) -> s1 + "," + s2);//获取所有id,并将id连接起来
        System.out.println(reduce);
}

3.收集

方法描述
collect(Collector c)将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中元素做汇总的方法

Collectors提供了一些方法,创建常见的List、Set、Map等。

@Test
public void test4(){
        //collect(Collector c)
        List<Person> list = getPerson();
        //Set<Person> collect = list.stream().filter(p -> p.getAge() > 30).collect(Collectors.toSet());
        List<Person> collect = list.stream().filter(p -> p.getAge() > 30).collect(Collectors.toList());

        collect.forEach(System.out::println);
}

关于将list集合转换为Map

转换为HashMap

Person类:

public class Person {
    private String id;
    private String name;
    private Integer age;
    //...
}

Collectors的toMap方法

public static <T, K, U>
    Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                                    Function<? super T, ? extends U> valueMapper) {
        return toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new);
    }

//T 输入元素
//K key映射函数的输出类型
//U value映射汗的输出类型
//keyMapper 产生key的映射函数
//valueMapper 产生value的映射函数

实例:

List<Person> list = new ArrayList<Person>();
list.add(new Person(...))
//...添加person元素
    
list.stream()
    .filter(p -> p.getName().contains("i"))//过滤
    .collection(Collectors.toMap(Person::getId,p->p))//收集
    .forEach((k,v)->System.out.println(k + ":" + v))

转换为LinkedHashMap

//Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
//                                Function<? super T, ? extends U> valueMapper,
//                                BinaryOperator<U> mergeFunction,
//                                Supplier<M> mapSupplier) {
        LinkedHashMap<String, Person> collect2 = list.stream()
                .collect(
                        Collectors.toMap(Person::getId,//返回key
                                p -> p,//返回value
                                (p1, p2) -> {
                                    Objects.requireNonNull(p1);
                                    Objects.requireNonNull(p2);
                                    if (p1.getId().equals(p2.getId())) {
                                            return p2;
                                    }
                                    return p1;
                                },//对于相同key如何处理
                                LinkedHashMap::new));//产生LinkedHashMap
        collect2.forEach((k,v) -> {
            System.out.println(k + ":" + v);
        });

最后

以上就是阔达裙子为你收集整理的StreamAPI基本使用StreamAPI的全部内容,希望文章能够帮你解决StreamAPI基本使用StreamAPI所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部