stream().filter集合过滤

stream().filter集合过滤

public class Test {
    public static void main(String[] args){
        List<Person> array = new ArrayList<>();
    array.add(new Person("AA",26,"男"));
    array.add(new Person("BB",26,"女"));
    array.add(new Person("DD",36,"男"));
    array.add( new Person("EE",46,"女"));
    array.add(new Person("FF",56,"男"));
    array.add(new Person("GG",56,"男"));

    /**
     * 按年龄降序/升序
     */
    //通过匿名内部类的方式重写Comparator比较器接口的compare方法
    Collections.sort(array, new Comparator<Person>() {

        // 升序排的话就是第一个参数.compareTo(第二个参数);
        // 降序排的话就是第二个参数.compareTo(第一个参数);
        @Override
        public int compare(Person o1, Person o2) {
            //升序
            return o1.getAge().compareTo(o2.getAge());
        }
    });
    System.out.println(array);

    //用Lambda表达式简化,只写我们关注的:传入的参数,返回的值
    Collections.sort(array,(p1,p2) -> p2.getAge().compareTo(p1.getAge()));//降序
    System.out.println(array);


    //更简洁地表明是通过那个属性的比较来进行排序,为什么说更简洁?因为comparing方法已经帮我们又封装了一层:
    //下面源码可见:(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));

    array.sort(Comparator.comparing(Person::getAge).reversed());//降序
    array.forEach(System.out::println);
     /**
     * comparing的源码:
     *
     *     public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
     *             Function<? super T, ? extends U> keyExtractor)
     *     {
     *         Objects.requireNonNull(keyExtractor);
     *         return (Comparator<T> & Serializable)
     *             (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
     *     }
     */

 //==========上面主要展示的就是关于集合根据属性值比较的排序===========

    
    //==============接着讲一下stream的API:filter============
    
    /**
     * 输出age大于36的Person对象
     */
    List<Person> collect = array.stream()  //获取stream对象
            .filter(s -> s.getAge() > 36)  //中间操作:filter -> 可理解为过滤
            .collect(Collectors.toList()); //终端输出:构建数据的输出
    System.out.println(collect);

    /**
     * 获取空字符串的数量。
     *
     * 不知天高地厚多说两句(可能有点飘):
     * 其实像用stream操作字符串、数组我相信大家都是很快上手的。
     * 因为无非就是filter(设置过滤的条件)、map(映射每个元素到对应的结果)、list(获取指定数量的流),
     * 但其实实际项目中操作字符串和数组是很少很少的,通常都是操作集合,如:集合之间的遍历比对,集合之间的转换、
     * 集合的排序(上面已介绍,如应用于项目中:商品列表的排序,同一个子目录的商品,但我就想某一个放在前面,因为那个
     * 商家给的广告费多,因此就可以为所有的商品都包含一个排序的属性,通过降序,设定属性值大的商品就会自动排在列表的前面。
     */
    List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
    long count = strings.stream().filter(string -> string.isEmpty()).count();




    //==============继续流程,stream的API-map:map 方法用于映射每个元素到对应的结果============

    /**
     * 获取对应的平方数并去重,distinct()可理解为去重,也很有意思,下面会展示
     */
    List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
    List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());



    //==============再继续流程,stream的API-limit:limit 方法用于获取指定数量的流============
    
    Random random = new Random();
    //生成10个[10,100)范围内的数据
    random.ints(1,10).limit(10).forEach(System.out::println);



    //==============流程未完,重点:stream的API-distinct:distinct 方法用于获取指定数量的流============
    /**
     * 对Person的属性age去重后输出所有的age
     */

    List<Integer> collect1 = array.stream()
            .map(Person::getAge)
            .distinct()
            .collect(Collectors.toList());
    collect1.sort(Comparator.naturalOrder());//升序,这里不是上面的对象排序,只是简单的元素排序

// collect1.sort(Comparator.reverseOrder());//降序
collect1.forEach(System.out::println);

    //其实distinct不一定是唯一的方法,由于Set集合的机制,一样可以办到。
    Set<Integer> collectSet = array.stream()
            .map(Person::getAge)
            .collect(Collectors.toSet());
    collect1.forEach(System.out::println);

    /**
     * 根据属性去重,打印去重后的属性似乎不是什么难事,但实际上Person对象本身并没有任何的改变
     *
     * 那如果根据属性去重,而去除对象呢?我在在实际项目中还没有遇到如此奇葩的场景,但学习一下其用法也无妨
     * 推荐博客:https://blog.csdn.net/haiyoung/article/details/80934467
     * 下面快速介绍用法:
     * 1、在Test类中实现distinctByKey方法,代码在最后。注意:不要写在main方法里
     * 2、然后就可以通过filter调用 distinctByKey去重,b -> b.getAge()可理解为去重b这个对象,依据是b的属性age。
     */
    List<Person> collect2 = array.stream()
            .filter(distinctByKey(b -> b.getAge()))
            .collect(Collectors.toList());
    collect2.forEach(b -> System.out.println(b.getName()+ "," + b.getAge()));


    //==============流程收尾,stream的API-reduce:reduce 方法用于累加
    Integer reduce = array.stream()
            .map(Person::getAge)
            .reduce(0, Integer::sum);
    System.out.println("sum = "+reduce);

    //==============流程完结,业务逻辑的巧点:List转化为Map============
    Map<String, String> map = array.stream()
            .collect(Collectors.toMap(Person::getName, Person::toString));
    map.entrySet().forEach(System.out::println);
    map.forEach((k,v)->System.out.println("name : " + k + " toString : " + v));
}

 }

/**
 * 配合对象去重的实现方法
 */
private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    Map<Object,Boolean> seen = new ConcurrentHashMap<>();
    return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值