如何在Java8中基于值合并对象的arraylist?

kuhbmx9i  于 2021-07-08  发布在  Java
关注(0)|答案(1)|浏览(381)

我想从不同的来源在一个列表数据库连接。某些来源可能/可能不提供url。
我想保留的记录有完整的信息(即dbname,connurl,isactive)+如果任何数据库没有与任何来源的完整记录。
record.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, url,y},{b,xyzurl,y}]
源gamma的列表3:[{a,y},{c,y}]
合并所有列表后,我们得到:
i/p列表:[{a,y},{b,y},{c,y},{d,y},{a, url,y},{b,xyz url,y},{a,y},{c,y}]
对于dbnamea,sourcebeta有完整的记录信息,所以我们将使用它
对于dbnameb,sourcebeta有完整的记录信息,所以我们将使用它
对于dbnamec,即使没有一个源代码有完整的信息,我们仍然会保留它,因为它是一个可用的db,并且某些源代码可能在将来的某个时候有url连接。对于dbname d,即使没有一个源代码有完整的信息,我们仍然会保留它,因为它是一个可用的db,并且某些源代码可能在将来的某个时候有url连接。
所需的o/p列表:[{a, url,y},{b,xyz url,y},{c,y},{d,y}]
有人能推荐Java8方法(使用流)吗?
老派的做法:

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());
m1m5dgzv

m1m5dgzv1#

它可以通过实现几个 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 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 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}]

相关问题