前言
Java8新特性我们使用的应该比较多了,今天这里整理了个人使用最多的8种场景,希望对大家有所帮助。
遍历
遍历也许是我们使用最多的功能了,在Java8之前我们遍历集合通常会采用for循环,迭代器,而在Java8中有了更加简介的方法:
public static void main(String[] args) {
List list = new ArrayList<>();
EmailModal email = new EmailModal();
email.setTitle("邮件名称");
list.add(email)
//方式一:普通流
list.stream().forEach(emailModal -> {
System.out.println(emailModal);
System.out.println(emailModal.getTitle());
});
//方式二:并行流
list.parallelStream().forEach(emailModal -> {
System.out.println(emailModal);
System.out.println(emailModal.getTitle());
});
}
方式二中,相当于使用了多线程去并行遍历,系统会根据运行服务器的资源占用情况自动进行分配。也正是因为并行流采用了多线程的方式去遍历数据,所以我们需要注意以下两点(自己遇到的坑,可能还会有其他的坑我没有发现):
1.避免在并行流中使用线程不安全的对象,比如ArrayList
2.主线程中ThreadLocal存储的线程局部变量,不能再并行流中获取
过滤
我们经常需要将集合中一些数据进行过滤,比如过滤集合中负数,过滤一些权限相关数据,在Java8之前我们更多的是使用迭代器进行remove操作,在Java8中有了两种更加简介的方法,其一:利用Collection的removeIf方法;其二:利用Stream的filter方法。
public static void main(String[] args) {
List list = new ArrayList<>();
EmailModal email = new EmailModal();
email.setHtml(true);
EmailModal email2 = new EmailModal();
email2.setHtml(false);
list.add(email);
list.add(email2);
//removeIf方法过滤html为false的对象
list.removeIf(emailModal -> !emailModal.isHtml());
//filter方法过滤掉html为true的对象
list = list.stream().filter(emailModal -> !emailModal.isHtml()).collect(Collectors.toList());
list.stream().forEach(emailModal -> {
System.out.println(emailModal);
System.out.println(emailModal.isHtml());
});
}
对于上面两种方法,我们需要区分一下,首先removeIf会将表达式中返回true的元素过滤掉,filter方法会将表达式中返回true的元素保留下来,两者是相反的。其次使用stream的filter方法过滤数据,如果想对List生效,则必须使用collect方法让list接收。
去重
去重我们经常也会使用到,对集合了解程度的不同,我们会使用不同的方法,比如最简单的方法遍历数据,使用新的空集合接受数据,利用contains方法判断是否在新集合中add元素,其次就是使用HashSet,我们不判断直接将元素放到Set中,利用集合的特效去重。但是在Java8中有更加简洁的方案,方案一:我们可以利用distinct()方法实现,如果去重元素不是基本类型而是对象的话,需要重写hashcode和equals方法,否则会去重失败。方案二:利用filter配合HashSet去除重复元素,set新增元素如果重复会返回false,刚好配合filter过滤false的特效
public static void main(String[] args) {
List list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("1");
//方案一
list.stream().distinct().forEach(s -> {
System.out.println(s);
});
//方案二
list.stream().filter(distinctByKey(String::trim)).forEach(s -> {
System.out.println(s);
});
}
private static Predicate distinctByKey(Function super T, ?> keyExtractor) {
Set
匹配
匹配数据也是我们常用的操作,比如我们需要在集合中找到属性ID为10的对象,将其取出,Java8之前我们通常会遍历集合,使用if判断,然后匹配到使用break跳出循环,但是在Java8中,我们可以使用anyMatch达到相同的效果。
public static void main(String[] args) {
List list = new ArrayList<>();
EmailModal email = new EmailModal();
email.setHtml(true);
EmailModal email2 = new EmailModal();
email2.setHtml(true);
list.add(email);
list.add(email2);
list.stream().anyMatch(emailModal -> {
if (emailModal.isHtml()) {
System.out.println(emailModal.isHtml());
//其他逻辑
return true;
}
return false;
});
}
拼接
开发接口的时候,前端会存在传递使用某个符号(逗号)隔开的字符串,我们通常会将其转换为集合,作为批量查询的条件。或者我们需要将集合转换为逗号隔开的字符。
String ids= "1,2,3,4,5,6";
//转集合
List listIds = Arrays.asList(ids.split(","))
.stream()
.map(s -> Integer.parseInt(s.trim()))
.collect(Collectors.toList());
System.out.println(listIds);
//转字符串
String str = listIds.stream()
.map(integer->integer.toString())
.collect(Collectors.joining(","));
System.out.println(str);
抽取单个属性
当我们调用一些第三方接口的时候,可能返回集合存储对象比较复杂,而我们只需要某个字段值的时候,我们可以通过map来实现这个效果
public static void main(String[] args) {
List list = new ArrayList<>();
EmailModal email = new EmailModal();
email.setHtml(true);
EmailModal email2 = new EmailModal();
email2.setHtml(true);
list.add(email);
list.add(email2);
List list2 = list.stream().map(emailModal -> emailModal.isHtml()).collect(Collectors.toList());
System.out.println(list2);
}
最值
获取集合中最大值和最小值方法有很多,比如排序后取值,或者遍历比较,在Java8中通过Stream的max和min方法我们很简单的实现这个功能
public static void main(String[] args) {
List list = new ArrayList<>();
QuestionBankVO questionBankVO = new QuestionBankVO();
questionBankVO.setId(2);
QuestionBankVO questionBankVO2 = new QuestionBankVO();
questionBankVO2.setId(4);
QuestionBankVO questionBankVO3 = new QuestionBankVO();
questionBankVO3.setId(5);
list.add(questionBankVO);
list.add(questionBankVO2);
list.add(questionBankVO3);
int maxVal = list.stream().
max(Comparator.comparingInt(QuestionBankVO::getId)).
get().
getId();
System.out.println(maxVal);
int minVal = list.stream().
min(Comparator.comparingInt(QuestionBankVO::getId)).
get().
getId();
System.out.println(minVal);
}
分组
就个人而言,将List转为Map的操作我遇到比较少,在Java8中可以通过groupingBy方法进行转换
public static void main(String[] args) {
List list = new ArrayList<>();
QuestionBankVO questionBankVO = new QuestionBankVO();
questionBankVO.setId(2);
questionBankVO.setCode("hello");
QuestionBankVO questionBankVO2 = new QuestionBankVO();
questionBankVO2.setId(2);
questionBankVO.setCode("hello2");
QuestionBankVO questionBankVO3 = new QuestionBankVO();
questionBankVO3.setId(5);
questionBankVO.setCode("hello3");
list.add(questionBankVO);
list.add(questionBankVO2);
list.add(questionBankVO3);
Map> map = list.stream().collect(Collectors.groupingBy(QuestionBankVO::getId));
for (Map.Entry> entry : map.entrySet()) {
System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
}
}