Stream流 JDK8新特性-方便的集合处理工具 一

理解Stream流的关键在于明确每一个方法的参数(在对流操作的方法中大多数需要传入一个接口)!

一、常用的函数式接口

1、Consumer接口(消费者)

@FunctionalInterface
public interface Consumer<T> {

 
    void accept(T t);


    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

 这里可以忽略default方法(同为jdk8的新特性)但与本次内容无关,只关注函数式接口的唯一抽象方法accept(T t) 

这个方法接受一个参数,并做无返回值的一些处理,相当于一个消费者,吸收了一个对象做了各种处理然后吞掉。

1.1Where use Consumer?

最常用的:Stream流操作中的foreach()

常见于list.stream().foreach(System.out::println)     <=>  list.stream().foreach((a)->System.out.print(a)) 

所以你可以看出,为什么foreach中要这么写,因为它需要一个Consumer接口。(看上去是句废话,但是对第一次看到这样写法的人,这句话是理解问题的关键)

2、Predicate接口(我愿意叫他仲裁者)

@FunctionalInterface
public interface Predicate<T> {

   
    boolean test(T t);

  
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

 
    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

  
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

  
    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }
}

老规矩只看唯一的抽象方法。这个接口功能很简单,你传一个值,我返回一个true或false。

2.1Where use Predicate?

这个接口说起来你感觉很迷茫,但是只要一用,立刻就会懂了比如Stream的filter方法:

Stream<T> filter(Predicate<? super T> predicate);

 public static void main(String[] args) {

        List<String> list = new ArrayList<>();
        list.add("");
        list.add(null);
        list.add("test");
        List<String> res = list.stream().filter((str)->str != null &&                 
        !str.isEmpty()).collect(Collectors.toList());
        System.out.println(res);
}

如果filter中的 Predicate接口的test方法返回true意味着这个数据不会被过滤,如果false则过滤掉。这个方法会经常出现因为筛选数据很方便,顺便一提stream中的方法几乎都自带了遍历所以不要奇怪为什么filter会过滤整个list。

3、Function接口(我愿意叫他转换者)

public interface Function<T, R> {

 
    R apply(T t);


    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }


    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }


    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

老规矩不说,这个apply方法要注意它的泛型,它的意思就是你传入一个值,我可以转换成别的类型的值,当然可以还是转换为原来类型这个就没人拦着了。

3.1Where use Function?

这个接口在Stream操作中用的也极为普遍,原因是map方法真的太好用了

<R> Stream<R> map(Function<? super T, ? extends R> mapper);
    public static void main(String[] args) {

        List<Person> personList = GeneratorPersonList();
        List<String> nameList = personList.stream().map((person)->person.getName()).collect(Collectors.toList());
        System.out.println(personList);
        System.out.println(nameList);
    }

忽略GeneratorPersonList(),这只是我自己编写的一个生成测试list用的(没什么技术含量)就知道这是一个Person的List

Person类(诺,就是个实体类):

public class Person {
    private long id;
    private String name;
    private int age;
    private String job;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    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 String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", job='" + job + '\'' +
                '}';
    }
}

于是,上面代码的意思就是遍历这个全是Person的List将其中的每一个元素Person对象都变成Person中的属性name,最后用collect方法生成一个新的list。(collect方法后面的章节会提到现在就理解为生成链式操作之后的list就好了)。

怎么样现在有没有感受到Stream的魅力,对于我这样接触不深的人来说,用了几遍之后的感觉就是,它是一个强大的清洗于数据处理工具,用于容器,让你省略了重复的遍历代码,清爽!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值