Java8常见操作整理

对象List处理

List转为HashMap

利用Collectors.toMap方法实现,若重复Key则覆盖。

1
2
3
4
5
6
7
8
9
10
// 值为对象
Map<String, Account> map = accountList.stream().collect(Collectors.toMap(Account::getUsername, Function.identity(), (key1, key2) -> key2));
// 值为字段
Map<Long, String> map = accountList.stream().collect(Collectors.toMap(Account::getId, Account::getUsername,(key1, key2) -> key2));
// 自定义键值
Map<String, String> dbCompanyFiledMap = dbCompanyFiledList.stream()
.collect(Collectors.toMap(
companyFiled -> companyFiled.getCompanyId() + companyFiled.getCompanyFiled(),//键
AchievementCompanyFiled::getReGroupFiled, //值
(key1, key2) -> key2));

List分组后得到HashMap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 根据某个字段分组
Map<String,List<AchievementVo>> tocheckMap = list.stream().collect(Collectors.groupingBy(AchievementVo::getCompanyId));
// 根据某个逻辑分组
Map<Integer,List<DeptInfoVo>> deptInfoVoMap = deptInfoVoList.stream().collect(Collectors.groupingBy(deptInfoVo -> deptInfoVo.getDeptCodeLevelList().size()));
// List分组并按照key排序
Map<String, List<JxSelfAssessmentCompanyVo>> map = list.stream().collect(Collectors.groupingBy(JxSelfAssessmentCompanyVo::getOrgId, LinkedHashMap::new, Collectors.toList()));
// 按评分项id分组、每一组元素按score升序排序
Map<String, List<ExpertScoreItemVo>> dbScoreItemVoMap = dbScoreItemVoList.stream()
.collect(Collectors.groupingBy(
ExpertScoreItemVo::getScoreItemId,
Collectors.collectingAndThen(
Collectors.toList(),
list -> { list.sort(Comparator.comparing(ExpertScoreItemVo::getScore));
return list;
}
)
));

把某个字段拆成List

1
List<String> idList = deptInfoVoList.stream().map(DeptInfoVo::getId).collect(Collectors.toList());

把某个字段拆成Set

1
2
3
Set<String> unitIdSet = measureUserList.stream()
.map(MeasureUser::getUnitId)
.collect(Collectors.toCollection(LinkedHashSet::new));

根据某一个对象属性去重

1
2
insertWbUserList = insertWbUserList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
() -> new TreeSet<>(Comparator.comparing(WbUser::getMobile))), ArrayList::new));

参考链接

根据多个对象属性去重

1
2
3
// 根据对象的多个属性去重
List<DeleteTaskDto> notRepetitiveList =deleteTaskList.stream()
.collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(item -> item.getAchievementId()+String.valueOf(item.getContrastId())))), ArrayList::new));

注意:item -> ‘不重复的字符串’。

根据某个字段分组、对另一个字段求和

1
2
// 根据id字段分组、求salary字段
Map<Integer, Double> salaryMap = workerList.stream().collect(Collectors.toMap(Worker::getId, Worker::getSalary, Double::sum));

Map处理

1
2
3
4
5
6
7
8
9
10
11
12
13
// 把Map转为List:按键升序排列
List<ImportErrorVo> list = errorMap.entrySet().stream().sorted(Comparator.comparing(e -> e.getKey()))
.map(e -> new ImportErrorVo(e.getKey(), e.getValue())).collect(Collectors.toList());
// 按照键排序
Map<String, List<JxSelfAssessmentCompanyVo>> sortedMap = unsortMap.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(oldValue, newValue) -> oldValue, LinkedHashMap::new));
// 按照值排序
Map<String, Integer> sortedMap = unsortMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(oldValue, newValue) -> oldValue, LinkedHashMap::new));

参考链接

单字段List处理

1
2
// 过滤、去重
List<String> specialSecondaryList = uniteNameList.stream().filter(item-> item.contains(DeptInfoConstant.SEPARATOR)).distinct().collect(toList());

对对象的字符串类型的日期排序(推荐)

方法一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Collections.sort(deptInfoVoList, new Comparator<DeptInfoVo>()
{
public int compare(DeptInfoVo deptInfoVo1, DeptInfoVo deptInfoVo2) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
try {
Date d1 = sdf.parse(deptInfoVo1.getDoneDate());
Date d2 = sdf.parse(deptInfoVo2.getDoneDate());
// 降序:d2.compareTo(d1)
return d1.compareTo(d2);
} catch (ParseException e) {
log.error("格式化时间失败,deptInfoVo1:{},deptInfoVo2:{}",deptInfoVo1,deptInfoVo2);
}
return 0;
}
});

方法二

1、实体类实现Comparable接口

1
2
public class DeptInfoVo implements Comparable<DeptInfoVo>{
}

2、重写compareTo方法

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
public int compareTo(DeptInfoVo deptInfoVo) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
try {
Date d1 = sdf.parse(this.getDoneDate());
Date d2 = sdf.parse(deptInfoVo.getDoneDate());
// 降序:d2.compareTo(d1)
return d1.compareTo(d2);
} catch (ParseException e) {
log.error("格式化时间失败:{}",e);
}
return 0;
}

3、业务代码中排序

1
Collections.sort(deptInfoVoList);

方法三

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
List<DeptInfoVo> newDeptInfoList = deptInfoVoList.stream().sorted(new Comparator<DeptInfoVo>() {
@Override
public int compare(DeptInfoVo deptInfoVo1, DeptInfoVo deptInfoVo2) {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
try {
Date d1 = dateFormat.parse(deptInfoVo1.getDoneDate());
Date d2 = dateFormat.parse(deptInfoVo2.getDoneDate());
// 降序:d2.compareTo(d1)
return d1.compareTo(d2);
} catch (ParseException e) {
log.error("格式化时间失败,deptInfoVo1:{},deptInfoVo2:{}",deptInfoVo1,deptInfoVo2);
}
return 0;
}
}).collect(Collectors.toList());

注意:日期格式化中的年份yyyy不能写为大写

参考链接

对对象的普通字符串(或日期类型)排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 升序
deptInfoVoList.sort(Comparator.comparing(DeptInfoVo::getDeptName));
// 降序
// Lambda表达式写法
Collections.sort(deptInfoVoList, (deptInfoVo1,deptInfoVo2)->deptInfoVo2.getAge().compareTo(deptInfoVo1.getAge()));
// Comparator.comparing写法(底层也是Lambda)
Collections.sort(deptInfoVoList, Comparator.comparing(DeptInfoVo::getAge).reversed());
// 匿名内部类写法
Collections.sort(deptInfoVoList, new Comparator<DeptInfoVo>() {
@Override
public int compare(DeptInfoVo deptInfoVo1, DeptInfoVo deptInfoVo2) {
return deptInfoVo2.getDeptName().compareTo(deptInfoVo1.getDeptName());
}
});

求对象数字类型的最小值和最大值

1
2
3
4
5
6
7
8
9
10
11
12
13
// 最小值
OptionalInt optionalInt = deptInfoVoList
.stream()
.mapToInt(DeptInfoVo::getAge).min();
System.out.println("最小年龄:"+optionalInt.getAsInt());
// 最大值
OptionalInt optionalInt = deptInfoVoList
.stream()
.mapToInt(DeptInfoVo::getAge).max();
System.out.println("最大年龄:"+optionalInt.getAsInt());

Optional<DeptInfoVo> deptInfoVo = deptInfoVoList.stream().max(Comparator.comparing(DeptInfoVo::getAge));
System.out.println("最大年龄:"+deptInfoVo.get());

注意:若age字段存在为空,会报空指针异常

求对象数字类型的总和和平均值

1
2
3
4
5
6
7
8
9
10
11
// 总和
int sum = deptInfoVoList
.stream()
.mapToInt(DeptInfoVo::getAge).sum();
System.out.println("年龄总和:"+sum);

// 平均值
OptionalDouble optionalDouble = deptInfoVoList
.stream()
.mapToInt(DeptInfoVo::getAge).average();
System.out.println("年龄平均值:"+optionalDouble.getAsDouble());

注意:若age字段存在为空,会报空指针异常