流式处理问题:从列表列表中获取属性的最佳方法



我创建了一个列表,列出了100个配置。我已将该列表划分为 10 组,所以现在我有List<List<Config>>.所有这些配置都有一个共同的属性值,即domainCode。我获得该属性的最佳方法是什么?假设配置域类如下所示:

public class Config {
private String configId;
private String portfolioId;
private String domainCode;
public Config(String configId, String portfolioId, String domainCode) {
this.configId = configId;
this.portfolioId = portfolioId;
this.domainCode = domainCode;
}
public String getConfigId() { return configId;}
public String getPortfolioSymbolCode() { return portfolioId;}
public String getDomainCode() { return domainCode; }
}

我构建了 100 个,然后将它们分组:

List<Config> configs = getAllConfigs();
List<List<Config>> partitionedConfigs = new ArrayList<>();
if (configs != null) {
AtomicInteger counter = new AtomicInteger();
partitionedConfigs.addAll(configs.stream()
.collect(Collectors.groupingBy(it -> counter.getAndIncrement() / 10))
.values());
}

partitionedConfigs传递给一种方法。该方法需要domainCode。从partitionedConfigs中获取单一domainCode的有效方法是什么?即使有 100 个Config对象,域代码也是唯一的,将只有一个域代码。这是我的方法需要找到的那个。

你可以从configs列表中获取它

List<String> domains = configs.stream()
.map(Config::getDomainCode)
.collect(Collectors.toList());

或者也从partitionedConfigs列表中

List<String> domains = partitionedConfigs.stream()
.flatMap(List::stream)
.map(Config::getDomainCode)
.collect(Collectors.toList());

如果列表中的每个对象都有相同的域名,那么您可以使用findFirst

String domain = configs.stream()
.findFirst()
.map(Config::getDomainCode)
.orElse(null); // if list is empty give some default value

partitionedConfigs列表

String domain = partitionedConfigs.stream()
.flatMap(List::stream)
.findFirst()
.map(Config::getDomainCode)
.orElse(null); // if list is empty give some 

如果您知道域代码在Config对象中是唯一的,则仍应检查此假设。

List<List<Config>> partitionedConfigs = // get from somewhere;
Set<String> uniqueDomainCode = partitionedConfigs.stream()
.flatMap(List::stream)
.map(Config::getDomainCode)
.collect(Collectors.toSet());
if (uniqueDomainCode.size() == 1) { // as expected
String domainCode = uniqueDomainCode.iterator().next();
// Do something with domain code
} else {
throw new IllegalStateException("Found " + uniqueDomainCode.size() + " domain codes, require 1");
}

当我们收集到一个Set,重复的域代码将被丢弃,因此我们最终应该得到一组大小为 1 的域名代码。在两种情况下,这将出错:

如果原始列表列表为空
  1. (外部列表为空或所有内部列表为空(,则集合的大小将为 0。
  2. 如果原始列表列表中有多个域代码,则大小将严格大于 1。

在这两种情况下,我们都想知道出了什么问题。例外是一种典型的信号方式,还有其他方式。

PS 如果您非常喜欢流媒体,以至于不想使用其他任何东西,那么这里有一种可能性:

String firstDomainCode = partitionedConfigs.stream()
.flatMap(List::stream)
.map(Config::getDomainCode)
.findAny()
.orElseThrow( () -> new IllegalStateException("Empty list, so no domain code found"));
boolean domainCodeIsUnique = partitionedConfigs.stream()
.flatMap(List::stream)
.map(Config::getDomainCode)
.allMatch(firstDomainCode::equals);
if (domainCodeIsUnique) {
// Do something with firstDomainCode
} else {
throw new IllegalStateException("Domain code is not unique, it is required to be");
}

最新更新