欧博充值:【Java8新特征】Stream API有哪些中心操作?看完你也可以吊打面试官!!

admin 3个月前 (07-08) 科技 61 1

写在前面

在上一篇《【Java8新特征】面试官问我:Java8中建立Stream流有哪几种方式?》中,一名读者去面试被面试官凶狠!归根结底,那哥儿们照样对Java8的新特征不是很领会呀!那么,我们继续讲述Java8的新特征,旨在最终可以让每位读者在跳槽面试的过程中吊打面试官!!

Stream的中心操作

多个中心操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中心操作不会执行任何的处置!而在终止操作时一次性所有处置,称为“惰性求值” 。 Stream的中心操作是不会有任何效果数据输出的。

Stream的中心操作在整体上可以分为:筛选与切片、映射、排序。接下来,我们就分别对这些中心操作举行简要的说明。

筛选与切片

这里,我将与筛选和切片有关的操作整理成如下表格。

方式 形貌
filter(Predicate p) 吸收Lambda表达式,从流中清扫某些元素
distinct() 筛选,通过流所生成元素的 hashCode() 和 equals() 去 除重复元素
limit(long maxSize) 截断流,使其元素不跨越给定数目
skip(long n) 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素 不足 n 个,则返回一个空流。与 limit(n) 互补

接下来,我们枚举几个简朴的示例,以便加深明了。

为了更好的测试程序,我先组织了一个工具数组,如下所示。

protected List<Employee> list = Arrays.asList(
    new Employee("张三", 18, 9999.99),
    new Employee("李四", 38, 5555.55),
    new Employee("王五", 60, 6666.66),
    new Employee("赵六", 8, 7777.77),
    new Employee("田七", 58, 3333.33)
);

其中,Employee类的界说如下所示。

@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Employee implements Serializable {
    private static final long serialVersionUID = -9079722457749166858L;
    private String name;
    private Integer age;
    private Double salary;
}

Employee类的界说对照简朴,这里,我就不赘述了。之后的示例中,我们都是使用的Employee工具的聚集举行操作。好了,我们最先详细的操作案例。

1.filter()方式

filter()方式主要是用于吸收Lambda表达式,从流中清扫某些元素,其在Stream接口中的源码如下所示。

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

可以看到,在filter()方式中,需要通报Predicate接口的工具,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);
    }
}

可以看到,Predicate是一个函数式接口,其中接口中界说的主要方式为test()方式,test()方式会吸收一个泛型工具t,返回一个boolean类型的数据。

看到这里,信赖人人明了了:filter()方式是凭据Predicate接口的test()方式的返回效果来过滤数据的,若是test()方式的返回效果为true,相符规则;若是test()方式的返回效果为false,则不相符规则。

这里,我们可以使用下面的示例来简朴的说明filter()方式的使用方式。

//内部迭代:在此过程中没有举行过迭代,由Stream api举行迭代
//中心操作:不会执行任何操作
Stream<Person> stream = list.stream().filter((e) -> {
    System.out.println("Stream API 中心操作");
    return e.getAge() > 30;
});

我们,在执行终止语句之后,一边迭代,一边打印,而我们并没有去迭代上面聚集,实在这是内部迭代,由Stream API 完成。

下面我们来看看外部迭代,也就是我们人为得迭代。

//外部迭代
Iterator<Person> it = list.iterator();
while (it.hasNext()) {
    System.out.println(it.next());
}

2.limit()方式

主要作用为:截断流,使其元素不跨越给定数目。

先来看limit方式的界说,如下所示。

Stream<T> limit(long maxSize);

limit()方式在Stream接口中的界说对照简朴,只需要传入一个long类型的数字即可。

我们可以根据如下所示的代码来使用limit()方式。

//过滤之后取2个值
list.stream().filter((e) -> e.getAge() >30 ).limit(2).forEach(System.out :: println);

在这里,我们可以配合其他得中心操作,并截断流,使我们可以取得响应个数得元素。而且在上面盘算中,只要发现有2条相符条件得元素,则不会继续往下迭代数据,可以提高效率。

3.skip()方式

跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素 不足 n 个,则返回一个空流。与 limit(n) 互补。

源码界说如下所示。

Stream<T> skip(long n);

源码界说对照简朴,同样只需要传入一个long类型的数字即可。其寄义是跳过n个元素。

简朴示例如下所示。

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

4.distinct()方式

筛选,通过流所生成元素的 hashCode() 和 equals() 去 除重复元素。

源码界说如下所示。

Stream<T> distinct();

旨在对流中的元素举行去重。

我们可以如下面的方式来使用disinct()方式。

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

这里有一个需要注重的地方:distinct 需要实体中重写hashCode()和 equals()方式才可以使用。

映射

关于映射相关的方式如下表所示。

方式 形貌
map(Function f) 吸收一个函数作为参数,该函数会被应用到每个元 素上,并将其映射成一个新的元素。
mapToDouble(ToDoubleFunction f) 吸收一个函数作为参数,该函数会被应用到每个元 素上,发生一个新的 DoubleStream。
mapToInt(ToIntFunction f) 吸收一个函数作为参数,该函数会被应用到每个元 素上,发生一个新的 IntStream。
mapToLong(ToLongFunction f) 吸收一个函数作为参数,该函数会被应用到每个元 素上,发生一个新的 LongStream
flatMap(Function f) 吸收一个函数作为参数,将流中的每个值都换成另 一个流,然后把所有流连接成一个流

1.map()方式

吸收一个函数作为参数,该函数会被应用到每个元 素上,并将其映射成一个新的元素。

先来看Java8中Stream接口对于map()方式的声明,如下所示。

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

我们可以根据如下方式使用map()方式。

//将流中每一个元素都映射到map的函数中,每个元素执行这个函数,再返回
List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd");
list.stream().map((e) -> e.toUpperCase()).forEach(System.out::printf);

//获取Person中的每一个人得名字name,再返回一个聚集
List<String> names = this.list.stream().map(Person :: getName).collect(Collectors.toList());

2.flatMap()

吸收一个函数作为参数,将流中的每个值都换成另 一个流,然后把所有流连接成一个流。

先来看Java8中Stream接口对于flatMap()方式的声明,如下所示。

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

我们可以使用如下方式使用flatMap()方式,为了便于人人明了,这里,我就贴出了测试flatMap()方式的所有代码。

/**
     * flatMap —— 吸收一个函数作为参数,将流中的每个值都换成一个流,然后把所有流连接成一个流
     */
    @Test
    public void testFlatMap () {
        StreamAPI_Test s = new StreamAPI_Test();
        List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd");
        list.stream().flatMap((e) -> s.filterCharacter(e)).forEach(System.out::println);

        //若是使用map则需要这样写
        list.stream().map((e) -> s.filterCharacter(e)).forEach((e) -> {
            e.forEach(System.out::println);
        });
    }

    /**
     * 将一个字符串转换为流
     */
    public Stream<Character> filterCharacter(String str){
        List<Character> list = new ArrayList<>();
        for (Character ch : str.toCharArray()) {
            list.add(ch);
        }
        return list.stream();
    }

实在map方式就相当于Collaction的add方式,若是add的是个聚集得话就会酿成二维数组,而flatMap 的话就相当于Collaction的addAll方式,参数若是是聚集得话,只是将2个聚集合并,而不是酿成二维数组。

排序

关于排序相关的方式如下表所示。

方式 形貌
sorted() 发生一个新流,其中按自然顺序排序
sorted(Comparator comp) 发生一个新流,其中按对照器顺序排序

从上述表格可以看出:sorted有两种方式,一种是不传任何参数,叫自然排序,另有一种需要传Comparator 接口参数,叫做定制排序。

先来看Java8中Stream接口对于sorted()方式的声明,如下所示。

Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);

sorted()方式的界说对照简朴,我就不再赘述了。

我们也可以根据如下方式来使用Stream的sorted()方式。

// 自然排序
List<Employee> persons = list.stream().sorted().collect(Collectors.toList());

//定制排序
List<Employee> persons1 = list.stream().sorted((e1, e2) -> {
    if (e1.getAge() == e2.getAge()) {
        return 0;
    } else if (e1.getAge() > e2.getAge()) {
        return 1;
    } else {
        return -1;
    }
}).collect(Collectors.toList());

写在最后

若是以为文章对你有点辅助,请微信搜索并关注「 冰河手艺 」微信民众号,跟冰河学习Java8新特征。

最后,附上Java8新特征焦点知识图,祝人人在学习Java8新特征时少走弯路。

,

欧博网址开户

www.aidshuhehaote.com欢迎进入欧博网址(Allbet Gaming),欧博网址开放会员注册、代理开户、电脑客户端下载、苹果安卓下载等业务。

Allbet声明:该文看法仅代表作者自己,与本平台无关。转载请注明:欧博充值:【Java8新特征】Stream API有哪些中心操作?看完你也可以吊打面试官!!

网友评论

  • (*)

最新评论

  • Allbet登录网址 2020-07-08 00:05:17 回复

    欧博亚洲客户端欢迎进入欧博亚洲客户端(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。图个开心

    1

文章归档

站点信息

  • 文章总数:480
  • 页面总数:0
  • 分类总数:8
  • 标签总数:948
  • 评论总数:151
  • 浏览总数:5598