如何使用 RxJava 和 Lambda 表达式一次在地图中插入两条记录
How to insert two records in map at a time using RxJava and Lambda expressions
我有一个记录列表,其中每条记录都有两个主键 Primary Id 和 Alternate Id。我想制作一个地图,通过它我可以使用主 ID 或使用 RxJava 操作的备用 ID 访问已处理的记录。
当前实施:
ImmutableMap.Builder<String, Record> mapBuilder = new ImmutableMap.Builder<>();
fetchRecords()
.forEach(
record -> {
parsedRecord = dosomething(record);
mapBuilder.put(parsedRecord.getPrimaryId(), parsedRecord);
mapBuilder.put(parsedRecord.getAlternativeId(), parsedRecord);
});
return mapBuilder.build();
我希望它看起来像:
fetchRecords().stream()
.map(doSomething)
.collect(Collectors.toMap(RecordData::getPrimaryId, Function.identity()));
// Need to add this as well
.collect(Collectors.toMap(RecordData::getAlterantiveId, Function.identity()));
只是想知道是否可以通过 fetchRecords() 一次传递将辅助 ID 添加到记录映射中。
我不熟悉 rx-java 但这可能会提供一个起点。创建自定义收集器以添加这两个键。这是一个非常基本的收集器,除了使用提供的最后一个之外,不处理重复键。我只是使用 Java 15 中引入的新 record
功能来创建一个不可变的 "class"
。对于常规 class.
这将以相同的方式工作
record ParsedRecord(String getPrimaryId,
String getAlternativeId, String someValue) {
@Override
public String toString() {
return someValue;
}
}
Map<String, ParsedRecord> map = records.stream()
.collect(twoKeys(ParsedRecord::getPrimaryId,
ParsedRecord::getAlternativeId, p -> p));
map.entrySet().forEach(System.out::println);
打印以下内容:
A=value1
B=value1
C=value2
D=value2
收藏家来了。它本质上是 toMap
的简化版本,使用两个键而不是一个。
private static <T, K, V> Collector<T, ?, Map<K, V>> twoKeys(
Function<T, K> keyMapper1, Function<T, K> keyMapper2,
Function<T, V> valueMapper) {
return Collector.of(
() -> new HashMap<K, V>(),
(m, r) -> {
V v = valueMapper.apply(r);
m.put(keyMapper1.apply(r),v);
m.put(keyMapper2.apply(r),v);
}, (m1, m2) -> {
m1.putAll(m2);
return m1;
}, Characteristics.UNORDERED);
}
或者保持简单高效。
Map<String, ParsedRecord> map = new HashMap<>();
for(ParsedRecord pr : records) {
map.put(pr.getPrimaryId(), pr);
map.put(pr.getAlternativeId(), pr);
}
我有一个记录列表,其中每条记录都有两个主键 Primary Id 和 Alternate Id。我想制作一个地图,通过它我可以使用主 ID 或使用 RxJava 操作的备用 ID 访问已处理的记录。
当前实施:
ImmutableMap.Builder<String, Record> mapBuilder = new ImmutableMap.Builder<>();
fetchRecords()
.forEach(
record -> {
parsedRecord = dosomething(record);
mapBuilder.put(parsedRecord.getPrimaryId(), parsedRecord);
mapBuilder.put(parsedRecord.getAlternativeId(), parsedRecord);
});
return mapBuilder.build();
我希望它看起来像:
fetchRecords().stream()
.map(doSomething)
.collect(Collectors.toMap(RecordData::getPrimaryId, Function.identity()));
// Need to add this as well
.collect(Collectors.toMap(RecordData::getAlterantiveId, Function.identity()));
只是想知道是否可以通过 fetchRecords() 一次传递将辅助 ID 添加到记录映射中。
我不熟悉 rx-java 但这可能会提供一个起点。创建自定义收集器以添加这两个键。这是一个非常基本的收集器,除了使用提供的最后一个之外,不处理重复键。我只是使用 Java 15 中引入的新 record
功能来创建一个不可变的 "class"
。对于常规 class.
record ParsedRecord(String getPrimaryId,
String getAlternativeId, String someValue) {
@Override
public String toString() {
return someValue;
}
}
Map<String, ParsedRecord> map = records.stream()
.collect(twoKeys(ParsedRecord::getPrimaryId,
ParsedRecord::getAlternativeId, p -> p));
map.entrySet().forEach(System.out::println);
打印以下内容:
A=value1
B=value1
C=value2
D=value2
收藏家来了。它本质上是 toMap
的简化版本,使用两个键而不是一个。
private static <T, K, V> Collector<T, ?, Map<K, V>> twoKeys(
Function<T, K> keyMapper1, Function<T, K> keyMapper2,
Function<T, V> valueMapper) {
return Collector.of(
() -> new HashMap<K, V>(),
(m, r) -> {
V v = valueMapper.apply(r);
m.put(keyMapper1.apply(r),v);
m.put(keyMapper2.apply(r),v);
}, (m1, m2) -> {
m1.putAll(m2);
return m1;
}, Characteristics.UNORDERED);
}
或者保持简单高效。
Map<String, ParsedRecord> map = new HashMap<>();
for(ParsedRecord pr : records) {
map.put(pr.getPrimaryId(), pr);
map.put(pr.getAlternativeId(), pr);
}