[英]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.