别再问问JDK的Stream怎么用了好么?面试官

开发 前端
关于Stream 会用就好,真到面试问到了,知道这些关键字都是干什么用的,也就可以了,如果还有人问这个好几年前的东西,那么这个公司好像也没有什么进去的必要了。你说是么?

JDK8发布到现在,已经过了8年的时间了,但是就是到现在,依然在面试的过程中,还有人问这个 JDK8 里面都优化了什么内容,对比 JDK7 来说,今天阿粉就再继续叨叨一次,真的是让面试官给整服气了。

JDK8 的 Stream

JDK8 要说牛,那是真的牛,让你的代码变的更加的简洁,为什么这么说,那就是因为 Stream 流的存在。

Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。

其实说这些话术类的,都是白搭,最主要的,还得是 Stream 的使用。

Stream的使用

筛选

其实筛选很简单,为什么这么说呢,因为筛选,比如我们现在有三个人,张三,李四,王五,年龄分别是 20 ,22,27,我们要筛选出年龄大于20的人,并且组合成一个新的结果集返回,那么代码肯定是:

List<User> userList = handleUser();
List<User> geUser = new ArrayList<>();
for (User user : userList) {
if (user.getAge() > 20){
geUser.add(user);
}
}

上面的handleUser只是一个赋值的操作,代码也放上:

handleUser(){
List<User> userList = new ArrayList<>();
User user = new User();
user.setId(UUID.randomUUID().toString());
user.setName("张三");
user.setAge(20);
user.setDept("开发部");
userList.add(user);

User user1 = new User();
user1.setId(UUID.randomUUID().toString());
user1.setName("李四");
user1.setAge(22);
user1.setDept("测试部");
userList.add(user1);

User user2 = new User();
user2.setId(UUID.randomUUID().toString());
user2.setName("王五");
user2.setAge(27);
user2.setDept("财务部");
userList.add(user2);

return userList;

}

这时候,我们获取到geUser这个结果集,就是我们筛选之后的,年龄大于20岁的人的数据。

那么如果使用 JDK8 的Stream 怎么来操作呢?

其实也不难

List<User> geUserStream = userList.stream().filter(e -> e.getAge() > 20).collect(Collectors.toList());

一行代码,直接来个链式编程,一行代码直接筛选出来,二者的结果都是一样的,区别只是在代码量上面,一个需要自己创建一个List 自己来操作,另外一个,直接不需要自己再创建了,直接在后面的 Collectors 给创建了,也是一种简化代码的方法。

循环

从这里我们来看 Stream 的循环,循环 for ,JDK7 和 JDK8 的循环的本质,并没啥变化,变化的只是开发者写的代码。我们直接来对比一下写法上的区别。

JDK7中的for循环
for (User user : collect) {
System.out.println("年龄大于20的人是:"+user.getName());
}

JDK8的for循环
collect.stream().forEach(vo->{
System.out.println("年龄大于20的人是:"+vo.getName());
});

循环区别好像并不大,看起来都挺方便的,所以使用什么,全看你自己。

聚合函数

为什么说聚合函数呢?这个聚合函数用的最多的地方,是不是在数据库中,我们获取吗,max,min,count 这些聚合字段的时候使用到的,如果你想要在程序中筛选,那么避免不了双层的for循环,然后去循环比对,或者是通过Collections 去处理,但是如果你使用 Stream 的话,那就很简单了。

//JDK7 获取List<String> 中字符串最长的那个
String[] strArr = new String[] { "cd", "ab", "ddfa", "sd", "zd" };
List<String> list = Arrays.asList(strArr);
String max = Collections.max(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
if (o1.length() < o2.length()) {
return -1;
}
if (o1.length() == o2.length()) {
return o1.compareTo(o2);
} else {
return 1;
}
}
});
System.out.println(max);

那么如果使用Stream 来获取呢?

JDK8获取List<String>中最长的字符串

String[] strArr = new String[] { "cd", "ab", "ddfa", "sd", "zd" };
List<String> list = Arrays.asList(strArr);
Optional<String> max = list.stream().max(Comparator.comparing(String::length));
System.out.println(max.get());

二者返回的结果也都是一模一样的,但是代码量来说,就不是一个层级了,至少 JDK8 能简化了许多的代码,至少在开发效率上面来说,就相对的比较快了。

min 也是同理,阿粉就不再赘述了,阿粉接下来说说这个 count 。一般count都会在哪些地方使用呢?

count()是获取流总数简写的方法。

其实和size就是一个意思,但是size我们是不能搭配一些filter使用的,但是count可以呀。

List<Integer> numList = Arrays.asList(42, 44, 43, 41); 

//获取List中大于43的元素的个数

long count = numList.stream().filter(e -> e > 43).count();
System.out.println(count);

这么一看,是不是感觉 Stream 里面的方法有时候也挺有用的,至少在代码上,能够让我们省下来不少时间。

Map

其实还有一些不是那么常用的,比如Map,这个的用法一般属于那种,不能够进行连表查询的情况,就比如我们现在有一个订单表,然后订单表中有关联的付款情况,这个时候就可能出现,一个订单,对应多种付款情况,但是如果要是数据量非常大的情况,反而不太适合使用连表的查询,于是只能先查询出订单,然后使用in的方式去查询付款情况。

我们继续用上面的 User 对象。

JDK7获取List中的Id数据:

//给List赋值
List<User> list = getList();
//新的IdList
List<String> Ids = new ArrayList<>();
for (User user: list) {
Ids.add(user.getId());
}

JDK8 获取Id数据

List<String> jdk8Ids = list.stream().map(User::getId).collect(Collectors.toList());
System.out.println("JDK8的获取数据==="+JSON.toJSON(jdk8Ids));

然后我们在用id去查询指定的数据就可以了。

关于Stream 会用就好,真到面试问到了,知道这些关键字都是干什么用的,也就可以了,如果还有人问这个好几年前的东西,那么这个公司好像也没有什么进去的必要了。你说是么?

责任编辑:武晓燕 来源: Java极客技术
相关推荐

2020-04-16 08:22:11

HTTPS加解密协议

2019-07-10 10:06:24

面试官三次握手四次挥手

2018-09-28 05:25:53

TopK算法代码

2018-10-28 22:37:00

计数排序排序面试

2018-11-01 13:49:23

桶排序排序面试

2020-09-24 14:40:55

Python 开发编程语言

2018-11-06 11:40:19

时间复杂度面试算法

2021-04-30 00:00:50

Semaphore信号量面试官

2021-06-08 08:33:23

NodeStream数据

2015-08-13 10:29:12

面试面试官

2019-04-16 13:30:05

表达式求值数据结构算法

2021-11-24 10:10:32

axios前端拦截器

2020-04-20 13:11:21

HashMap底层存储

2021-07-09 10:11:34

Redis云数据技术

2021-04-12 21:34:29

Redis故障数据

2022-05-23 08:43:02

BigIntJavaScript内置对象

2019-11-19 16:10:24

面试官Java编程语言

2021-01-20 07:16:07

幂等性接口token

2019-01-08 15:11:50

最大值最小值算法

2022-10-12 14:39:27

Streammappeek
点赞
收藏

51CTO技术栈公众号