我有一個大小來自查詢的List<Object[]>地方。查詢結果如下:Object[]3
| vehicleId | modelId | serviceId |
|------------------------------------|---------|-----------------|
|93bf3e92-7a37-4e23-836d-eed5a104341f| 214|80a7-ce5640b18879|
|b4066520-e127-44b7-bcc0-1d1187de559c| 214|80a7-ce5640b18879|
|ae6cb0fe-1501-4311-a2b4-cfb8b4f51ca4| 214|80a7-ce5640b18879|
|cf80ff11-6e23-4c19-8b6d-55d34d131566| 214|80a7-ce5640b18879|
它應該映射在下面的串列中。第二列和最后一列將映射到 modelId 和 serviceId,而第一列應成為車輛 ID 串列。
我需要將其映射到如下所示的List<MyDTO>位置:MyDTO
MyDTO{
// constructor
MyDTO(String modelId, String serviceId, List<String> vehicleIds){...}
String modelId;
String serviceId;
List<String> vehicleIds;
}
我試圖弄清楚如何在流中分組,但似乎沒有任何結果。這就是我被封鎖的地方...
listOfObjectArrays.stream()
.map(objects -> new MyDTO((String) objects[0], (String) objects[1], null));
無法弄清楚如何應用減少操作來完成這項作業,任何幫助都非常感謝!
編輯: 對不起,我忘了提到我被 Java 8 困住了。謝謝大家的精彩回答。
uj5u.com熱心網友回復:
您可以先將它們全部映射到字串,然后按元組 (modelId, serviceId) 進行分組,然后才將分組結果映射到 dto。
List<MyDto> myDtos = queryResult.stream()
.map(objects -> List.of((String) objects[0], (String) objects[1], (String) objects[2])
.collect(Collectors.groupingBy(r -> List.of(r.get(0), r.get(1)))
.entrySet().stream()
.map(entry -> new MyDto(entry.getKey().get(0), entry.getKey().get(1), entry.getValue()))
.collect(toList());
ResultRow如果您使用的是 JDK14 ,我建議您使用名為 的記錄,而不是第一個地圖中的串列,以提高可讀性或強制解決它(沒有流)。
uj5u.com熱心網友回復:
如果您不一定需要使用stream,您始終可以使用標準回圈,例如:
Map<String, MyDTO> myDTOs = new HashMap<>();
for(Object[] a : listOfObjectArrays) {
String key = a[1] " - " a[2];
MyDTO myDTO = myDTOs.get(key);
if(myDTO == null) {
List<String> vehicleIds = new ArrayList<>();
vehicleIds.add((String) a[0]);
myDTO = new MyDTO((String) a[1], (String) a[2], vehicleIds);
myDTOs.put(key, myDTO);
} else {
myDTO.getVehicleIds().add((String) a[0]);
}
}
List<MyDTO> myDTOList = new ArrayList<>(myDTOs.values());
uj5u.com熱心網友回復:
您可以通過使用和收集器對資料進行分組modelId,然后serviceId使用收集器來創建嵌套中間圖。groupingBy()mapping()
然后在條目集上創建一個流。new MyDTO并展平基于 和 的每個組合modelId創建的每個內部地圖serviceId。
Map<String, Map<String, List<String>>> vehicleIdByModelIdAndServiceId =
listOfObjectArrays.stream()
.collect(Collectors.groupingBy(objects -> (String) objects[1],
Collectors.groupingBy(objects -> (String) objects[2],
Collectors.mapping(objects -> (String) objects[0],
Collectors.toList()))));
List<MyDTO> result = vehicleIdByModelIdAndServiceId.entrySet().stream()
.flatMap(baseEntry -> baseEntry.getValue().entrySet().stream()
.map(entry -> new MyDTO(baseEntry.getKey(), entry.getKey(), entry.getValue())))
.collect(Collectors.toList());
另一種選擇是使用 aMap.Entry作為中間映射中的鍵,值將是vehicleId.
List<MyDTO> result = listOfObjectArrays.stream()
.collect(Collectors.groupingBy(objects -> new AbstractMap.SimpleEntry<>((String) objects[1], (String) objects[2]),
Collectors.mapping(objects -> (String) objects[0],
Collectors.toList())))
.entrySet().stream()
.map(entry -> new MyDTO(entry.getKey().getKey(),
entry.getKey().getValue(),
entry.getValue()))
.collect(Collectors.toList());
uj5u.com熱心網友回復:
這個想法是
- 流式傳輸
Object[]為{String,Long,String} - 分組方式
{Object[1],Object[2]};收集(不同Object[0]) Map<List<Object[0]>,{Object[1],Object[2]}>-->List<MyDto>
為此,我設定了兩個支持類,其中一個由您提供,另一個需要作為 KeygroupingBuy才能作業:
class MyDTO{
String modelId;
String serviceId;
List<String> vehicleIds;
MyDTO(String modelId, String serviceId, String vehicleId) {
// Need to put in a Modifiable ArrayList so the reduce can happen
this(modelId,serviceId,new ArrayList<>(List.of(vehicleId)));
}
MyDTO(String modelId, String serviceId, List<String> vehicleIds){
this.modelId = modelId;
this.serviceId = serviceId;
this.vehicleIds = vehicleIds;
}
public MyDTOKey getKey() {
return new MyDTOKey(modelId, serviceId);
}
public MyDTO reduce(MyDTO other) {
this.vehicleIds.addAll(other.vehicleIds);
return this;
}
public void dump() {
System.out.println("modelId: " modelId "; serviceId: " serviceId "; vehicleIds: " vehicleIds.toString());
}
}
private class MyDTOKey<T1,T2> {
T1 v1;
T2 v2;
public MyDTOKey(T1 v1,T2 v2) {
this.v1 = v1;
this.v2 = v2;
}
@Override
public int hashCode() {
return Objects.hash(v1,v2);
}
/*
* Required for the groupby to work correctly as it
* doesnt automatically on an Object[]
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final MyDTOKey <?, ?> other = (MyDTOKey <?, ?>) obj;
if (!Objects.equals(this.v1, other.v1)) {
return false;
}
return Objects.equals(this.v2, other.v2);
}
}
通過正面的方法,我可以構建這樣的東西:
List<Object []> data = List.of(
new Object[]{"93bf3e92-7a37-4e23-836d-eed5a104341f", "214", "80a7-ce5640b18879"},
new Object[]{"b4066520-e127-44b7-bcc0-1d1187de559c", "214", "80a7-ce5640b18879"},
new Object[]{"b4066520-e127-44b7-bcc0-dddddddddddd", "215", "80a7-ce5640b18879"}
);
public static void main(String [] pars) {
Map<Pair<String,String>,List<String>> map = data
.stream()
.collect(groupingBy(
o->new MyDTOKey((String)o[1],(String)o[2]), // group by last two only
mapping(
o->(String)o[0], // Collapse the vehicle id's to a list
toList() // Using set to take out duplicate vehicle id's
)
));
// Convert the map to a List.
List<MyDTO> dtos = map.entrySet().stream()
.map(e->new MyDTO(e.getKey().v1,e.getKey().v2,e.getValue()))
.collect(toList());
for (MyDTO dto:dtos) {
dto.dump();
}
}
通過將其設定為@Valerij Doblers 回答中所做的那樣,MyDTOKey可以避免創建一個表示元組 ( ) 的類的全部作業。List<String>
但是已經對MyDTO類進行了一些小的調整,我們也可以巧妙地重寫它,如下所示:
public static void main(String [] pars) {
List<MyDTO> data = List.of(
new MyDTO("214", "80a7-ce5640b18879","93bf3e92-7a37-4e23-836d-eed5a104341f"),
new MyDTO("214", "80a7-ce5640b18879","b4066520-e127-44b7-bcc0-1d1187de559c"),
new MyDTO("215", "80a7-ce5640b18879","b4066520-e127-44b7-bcc0-dddddddddddd")
);
List<MyDTO> dtos = data.stream()
.collect(
groupingBy(
MyDTO::getKey,
reducing(MyDTO::reduce)
)
) // Produces a Map<MyDTOKey,MyDTO>
.values().stream() // Streams Optional<MyDTO>
.flatMap(o->o.stream()) // expand to contained MyDTO
.collect(toList())
;
for (MyDTO dto:dtos) {
dto.dump();
}
}
也許再花點功夫,我們可以直接在 List 中收集,而無需先通過 Map。
uj5u.com熱心網友回復:
這需要一個 Collectors.groupBy() 函式,因為您正在獲取流并將它們分組在一起。
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
class F {
public static void main(String[] args) {
var in = List.of(new Object[]{"93bf3e92-7a37-4e23-836d-eed5a104341f", "214", "80a7-ce5640b18879"},
new Object[]{"b4066520-e127-44b7-bcc0-1d1187de559c", "214", "80a7-ce5640b18879"},
new Object[]{"b4066520-e127-44b7-bcc0-dddddddddddd", "215", "80a7-ce5640b18879"}
);
Map<Key, List<MyDTOOne>> p1 =
in.stream()
.map(objs -> new String[]{(String) objs[0], (String) objs[1], (String) objs[2]})
.map(objs -> new MyDTOOne(objs[1], objs[2], objs[0]))
.collect(Collectors.groupingBy(myDTO -> new Key(myDTO.modelId, myDTO.serviceId)));
List<MyDTO> p2 = p1.entrySet()
.stream()
.map(e -> new MyDTO(e.getKey().modelId, e.getKey().serviceId, e.getValue().stream().map(MyDTOOne::vehicleId).toList()))
.toList();
System.out.println(p2);
}
static record Key(String modelId, String serviceId) {
}
static record MyDTO(String modelId, String serviceId, List<String> vehicleIds) {
}
static record MyDTOOne(String modelId, String serviceId, String vehicleId) {
}
}
https://replit.com/@ArchimedesTraja/Grouping
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/466070.html
上一篇:將2個串列相乘
