根据公共字段对不同类型的对象进行分组
Grouping objects of different types based on common fields
我想根据类 上字段incomeCode
、endDate
和codeRef
的相同内容对不同的对象类型进行分组。为了简单起见,我省略了两个 类 上的许多字段,这些字段使每个对象都是唯一的。
public class Exon {
private Long id;
private IncomeCode incomeCode;
private LocalDate endDate;
String codeRef;
}
public class Sup {
private Long id;
private IncomeCode incomeCode;
private LocalDate startDate;
private LocalDate endDate;
String codeRef;
}
外显子示例:
id
incomdeCode
endDate
codeRef
1
45
01/01/2021
4
2
21
01/01/2022
5
3
33
01/01/2023
2
4
45
01/01/2021
4
支持示例:
id
incomdeCode
endDate
codeRef
1
45
01/01/2021
4
2
21
01/01/2022
5
3
33
01/01/2023
2
期望的结果:
列表:{ {exon1, exon4, sup1}, {exon2, sup2}, {exon3, sup3} }
我的尝试:
public Map<Object, List<Exon>> getExons() {
Map<Object, List<Exon>> result = getSource1.stream()
.flatMap(lp -> lp.getExons().stream())
.collect(Collectors.groupingBy(e -> new KeyGroup(e.getIncomeCode(), e.getEndDate(), e.getCodeRef())
));
return result;
}
public Map<Object, List<Sup>> getSups() {
Map<Object, List<Sup>> result = getSource2.stream()
.flatMap(lp -> lp.getSups().stream())
.collect(Collectors.groupingBy(e -> new
KeyGroup(e.getIncomeCode(), e.getEndDate(), e.getCodeRef())));
return result;
}
Map<Object, List<Exon>> exonList = getExons();
Map<Object, List<Sup>> supList = getSups();
Map<Object, List<List<?>>> objMap = new HashMap<>();
exonList.forEach((k, v) -> {
if (objMap.containsKey(o)) {
objMap.get(o).add(v);
} else {
List<List<?>> eList = new ArrayList<>();
eList.add(v);
objMap.put(o, eList);
}
});
supList.forEach((o, v) -> {
if (objMap.containsKey(o)) {
objMap.get(o).add(v);
} else {
List<List<?>> eList = new ArrayList<>();
eList.add(v);
objMap.put(o, eList);
}
});
这样的事情怎么样。您可以制作另一个子class 并在这张地图
上将您的不同class 项目分组
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Solution
{
public void sol()
{
List<Exon> exons = new ArrayList<>();
List<Sup> sups = new ArrayList<>();
List<ClassWithNeededFields> list1 = exons.stream()
.map(item -> new ClassWithNeededFields(item.getIncomeCode(), "neededField"))
.collect(Collectors.toList());
List<ClassWithNeededFields> list2 = sups.stream()
.map(item -> new ClassWithNeededFields(item.getIncomeCode(), "neededField"))
.collect(Collectors.toList());
list1.addAll(list2);
Map<IncomeCode, List<ClassWithNeededFields>> map2 = list1.stream()
.map(item -> new ClassWithNeededFields(item.getIncomeCode(), "neededField"))
.collect(Collectors.groupingBy(ClassWithNeededFields::getIncomeCode));
}
public class Exon
{
private IncomeCode incomeCode;
public IncomeCode getIncomeCode()
{
return null;
}
}
public class Sup
{
private IncomeCode incomeCode;
public IncomeCode getIncomeCode()
{
return null;
}
}
public class IncomeCode
{
}
public class ClassWithNeededFields
{
private IncomeCode incomeCode;
private String otherField;
// The other needed fields. ...
public ClassWithNeededFields(IncomeCode incomeCode, String otherField /* The other needed fields. ... */)
{
}
public IncomeCode getIncomeCode()
{
return this.incomeCode;
}
}
}
正如评论中指出的那样,如果您需要混合不同类型的对象,您得到的 List
将是 List<List<Object>>
.
要按这样对它们进行分组,您可以将 collect()
终端操作与 Collectors.groupingBy()
结合使用,后者可以使用具有所需字段的 ad-hoc 构建的键对对象进行分组(incomeCode
、endDate
和 codeRef
)。构建 Map
后,您可以检索其值,即带有对象列表的 Collection
,并将它们作为 List
实现的转换构造函数的输入。
List<List<Object>> listRes = new ArrayList<>(Stream.concat(listExon.stream(), listSup.stream())
.collect(Collectors.groupingBy(obj -> {
if (obj instanceof Exon) {
Exon exon = (Exon) obj;
return String.format("%s-%s-%s", exon.getIncomeCode(), exon.getEndDate(), exon.getCodeRef());
}
Sup sup = (Sup) obj;
return String.format("%s-%s-%s", sup.getIncomeCode(), sup.getEndDate(), sup.getCodeRef());
})).values());
这里还有一个link来测试上面的代码:
我想根据类 上字段incomeCode
、endDate
和codeRef
的相同内容对不同的对象类型进行分组。为了简单起见,我省略了两个 类 上的许多字段,这些字段使每个对象都是唯一的。
public class Exon {
private Long id;
private IncomeCode incomeCode;
private LocalDate endDate;
String codeRef;
}
public class Sup {
private Long id;
private IncomeCode incomeCode;
private LocalDate startDate;
private LocalDate endDate;
String codeRef;
}
外显子示例:
id | incomdeCode | endDate | codeRef |
---|---|---|---|
1 | 45 | 01/01/2021 | 4 |
2 | 21 | 01/01/2022 | 5 |
3 | 33 | 01/01/2023 | 2 |
4 | 45 | 01/01/2021 | 4 |
支持示例:
id | incomdeCode | endDate | codeRef |
---|---|---|---|
1 | 45 | 01/01/2021 | 4 |
2 | 21 | 01/01/2022 | 5 |
3 | 33 | 01/01/2023 | 2 |
期望的结果: 列表:{ {exon1, exon4, sup1}, {exon2, sup2}, {exon3, sup3} }
我的尝试:
public Map<Object, List<Exon>> getExons() {
Map<Object, List<Exon>> result = getSource1.stream()
.flatMap(lp -> lp.getExons().stream())
.collect(Collectors.groupingBy(e -> new KeyGroup(e.getIncomeCode(), e.getEndDate(), e.getCodeRef())
));
return result;
}
public Map<Object, List<Sup>> getSups() {
Map<Object, List<Sup>> result = getSource2.stream()
.flatMap(lp -> lp.getSups().stream())
.collect(Collectors.groupingBy(e -> new
KeyGroup(e.getIncomeCode(), e.getEndDate(), e.getCodeRef())));
return result;
}
Map<Object, List<Exon>> exonList = getExons();
Map<Object, List<Sup>> supList = getSups();
Map<Object, List<List<?>>> objMap = new HashMap<>();
exonList.forEach((k, v) -> {
if (objMap.containsKey(o)) {
objMap.get(o).add(v);
} else {
List<List<?>> eList = new ArrayList<>();
eList.add(v);
objMap.put(o, eList);
}
});
supList.forEach((o, v) -> {
if (objMap.containsKey(o)) {
objMap.get(o).add(v);
} else {
List<List<?>> eList = new ArrayList<>();
eList.add(v);
objMap.put(o, eList);
}
});
这样的事情怎么样。您可以制作另一个子class 并在这张地图
上将您的不同class 项目分组import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Solution
{
public void sol()
{
List<Exon> exons = new ArrayList<>();
List<Sup> sups = new ArrayList<>();
List<ClassWithNeededFields> list1 = exons.stream()
.map(item -> new ClassWithNeededFields(item.getIncomeCode(), "neededField"))
.collect(Collectors.toList());
List<ClassWithNeededFields> list2 = sups.stream()
.map(item -> new ClassWithNeededFields(item.getIncomeCode(), "neededField"))
.collect(Collectors.toList());
list1.addAll(list2);
Map<IncomeCode, List<ClassWithNeededFields>> map2 = list1.stream()
.map(item -> new ClassWithNeededFields(item.getIncomeCode(), "neededField"))
.collect(Collectors.groupingBy(ClassWithNeededFields::getIncomeCode));
}
public class Exon
{
private IncomeCode incomeCode;
public IncomeCode getIncomeCode()
{
return null;
}
}
public class Sup
{
private IncomeCode incomeCode;
public IncomeCode getIncomeCode()
{
return null;
}
}
public class IncomeCode
{
}
public class ClassWithNeededFields
{
private IncomeCode incomeCode;
private String otherField;
// The other needed fields. ...
public ClassWithNeededFields(IncomeCode incomeCode, String otherField /* The other needed fields. ... */)
{
}
public IncomeCode getIncomeCode()
{
return this.incomeCode;
}
}
}
正如评论中指出的那样,如果您需要混合不同类型的对象,您得到的 List
将是 List<List<Object>>
.
要按这样对它们进行分组,您可以将 collect()
终端操作与 Collectors.groupingBy()
结合使用,后者可以使用具有所需字段的 ad-hoc 构建的键对对象进行分组(incomeCode
、endDate
和 codeRef
)。构建 Map
后,您可以检索其值,即带有对象列表的 Collection
,并将它们作为 List
实现的转换构造函数的输入。
List<List<Object>> listRes = new ArrayList<>(Stream.concat(listExon.stream(), listSup.stream())
.collect(Collectors.groupingBy(obj -> {
if (obj instanceof Exon) {
Exon exon = (Exon) obj;
return String.format("%s-%s-%s", exon.getIncomeCode(), exon.getEndDate(), exon.getCodeRef());
}
Sup sup = (Sup) obj;
return String.format("%s-%s-%s", sup.getIncomeCode(), sup.getEndDate(), sup.getCodeRef());
})).values());
这里还有一个link来测试上面的代码: