![](/img/trans.png)
[英]JAVA: How do I merge objects from an arrayList based on a property value?
[英]How to merge ArrayList of Objects based on value in java 8?
我想在來自各種來源的列表中建立數據庫連接。 某些來源可能/可能不提供 URL。
我想保留具有完整信息的記錄(即 dbName、connUrl、isActive)+ 如果任何數據庫沒有任何來源的完整記錄。
記錄.java,
String dbName;
String connUrl;
String isActiveYN;
主應用程序.java,
List <Record> connRecords = new ArrayList<>();
connRecords = someFunc(sourceName) // some func takes source as param and returns connection List
connRecords.addAll(someFunc(sourceName));
connRecords.addAll(someFunc(sourceName));
//logic for getting all unique DBs
例如:來自源 Alpha 的列表 1:[{A,Y},{B,Y},{C, Y},{D,Y}]
源 Beta 中的列表 2:[{A, abc-url, Y}, {B, xyz-url, Y}]
源 Gamma 中的列表 3:[{A,Y},{C,Y}]
合並所有列表后,我們得到:
I/P 列表:[{A,Y}, {B,Y}, {C, Y}, {D,Y}, {A, abc-url, Y}, {B, xyz-url, Y}, {A,Y}, {C,Y}]
對於 dbName A,源 Beta 具有完整的記錄信息,因此我們將采用
對於 dbName B,源 Beta 具有完整的記錄信息,因此我們將采用
對於 dbName C,即使沒有一個來源有完整的信息,我們仍然會保留它,因為它是一個可用的數據庫,並且某些來源可能在未來的某個時候具有 url 連接。 對於 dbName D,即使沒有一個來源有完整的信息,我們仍然會保留它,因為它是一個可用的數據庫,並且某些來源可能在未來的某個時候具有 url 連接。
所需的 O/P 列表:[{A,abc-url,Y}, {B,xyz-url,Y}, {C,Y},{D,Y}]
任何人都可以建議使用 java 8 方式(使用流)來執行此操作嗎?
這樣做的老派方式:
Map<String, Record> map = new HashMap<>();
for (Record record: recordList) {
String dbName = record.getDBName();
String isActiveYN = record.getIsActiveYN();
if (map.containsKey(dbName)) {
if(record.getConnURL() != null)
map.replace(dbName, record);
} else {
map.put(dbName, record);
}
}
List<Record> merged = new ArrayList<>(map.values());
它可以通過實現幾個merge
函數來實現:
Record
實例合並為一個String
實例合並為一個toString
方法以提供所需的輸出isActiveN
設置:如果需要合並,則設置為Y
// using Lombok annotations for brevity
@Data
@AllArgsConstructor
@EqualsAndHashCode
class Record {
String dbName;
String connUrl;
String isActiveYN;
Record merge(Record other) {
if (this.dbName.equals(other.dbName)) {
this.connUrl = merge(this.connUrl, other.connUrl);
this.isActiveYN = "Y"; // if merge called, there are at least two entries
}
return this;
}
static String merge(String thiss, String thats) {
return thiss == null ^ thats == null ? (thiss == null ? thats : thiss) : thiss;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
String sep = "";
if (null != dbName) {
sb.append(dbName);
sep = ", ";
}
if (null != connUrl) {
sb.append(sep).append(connUrl);
sep = ", ";
}
if (null != isActiveYN) {
sb.append(sep).append(isActiveYN);
}
sb.insert(0, '{');
sb.append('}');
return sb.toString();
}
}
然后可以像使用Collectors.toMap
器一樣簡單地合並記錄,並將對Record::merge
引用作為第三個參數傳遞:
// Source Alpha
List<Record> connRecords = new ArrayList<>(Arrays.asList(
new Record("A", null, "N"),
new Record("B", null, "Y"),
new Record("C", null, null),
new Record("D", null, "N")
));
// Source Beta
connRecords.addAll(Arrays.asList(
new Record("A", "abc-url", null),
new Record("B", "xyz-url", "N")
));
// Source Gamma
connRecords.addAll(Arrays.asList(
new Record("A", null, "N"),
new Record("C", null, "N")
));
List<Record> merged = new ArrayList<>(
connRecords.stream()
.collect(Collectors.toMap(Record::getDbName, rec -> rec, Record::merge))
.values()
);
System.out.println(merged);
輸出:
[{A, abc-url, Y}, {B, xyz-url, Y}, {C, Y}, {D, N}]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.