gpt4 book ai didi

java - List 到 Java 8 中的 Map

转载 作者:搜寻专家 更新时间:2023-10-30 19:42:29 29 4
gpt4 key购买 nike

通常需要转换查询的结果,例如:

select category, count(*)
from table
group by category

到一个 map ,其中键是类别,值是属于同一类别的记录数。

许多持久性框架返回这样的查询结果 List<Object[]> ,其中对象数组包含两个元素(每个返回的结果集行的类别和计数)。

我正在尝试找到最易读的方式将此列表转换为相应的 map 。

当然,传统方法会涉及创建 map 并手动放置条目:

Map<String, Integer> map = new HashMap<>();
list.stream().forEach(e -> map.put((String) e[0], (Integer) e[1]));

我想到的第一个单线是利用现成可用的 Collectors.toMap Collection 家:

Map<String, Integer> map = list.stream().collect(toMap(e -> (String) e[0], e -> (Integer) e[1]));

但是,我发现这个e -> (T) e[i]语法比传统方法可读性差一点。为了克服这个问题,我可以创建一个 util 方法,我可以在所有这些情况下重复使用它:

public static <K, V> Collector<Object[], ?, Map<K, V>> toMap() {
return Collectors.toMap(e -> (K) e[0], e -> (V) e[1]);
}

然后我得到了一个完美的单行:

Map<String, Integer> map = list.stream().collect(Utils.toMap());

因为类型推断,甚至不需要转换 key 和 value。但是,对于代码的其他读者来说,这有点难以理解(util 方法签名中的 Collector<Object[], ?, Map<K, V>> 等)。

我想知道,java 8 工具箱中是否还有其他任何东西可以帮助以更具可读性/优雅的方式实现这一目标?

最佳答案

我认为您当前的“单行”很好。但是如果你不是特别喜欢命令中内置的魔法索引,那么你可以封装在一个枚举中:

enum Column {
CATEGORY(0),
COUNT(1);

private final int index;

Column(int index) {
this.index = index;
}

public int getIntValue(Object[] row) {
return (int)row[index]);
}

public String getStringValue(Object[] row) {
return (String)row[index];
}
}

然后你的提取代码就变得更清晰了:

list.stream().collect(Collectors.toMap(CATEGORY::getStringValue, COUNT::getIntValue));

理想情况下,您应该向该列添加一个类型字段并检查是否调用了正确的方法。

虽然超出了您的问题范围,但理想情况下,您将创建一个表示封装查询的行的类。类似于以下内容(为清楚起见,跳过了 setter/getter ):

class CategoryCount {
private static final String QUERY = "
select category, count(*)
from table
group by category";

private final String category;
private final int count;

public static Stream<CategoryCount> getAllCategoryCounts() {
list<Object[]> results = runQuery(QUERY);
return Arrays.stream(results).map(CategoryCount::new);
}

private CategoryCount(Object[] row) {
category = (String)row[0];
count = (int)row[1];
}
}

这将查询和行解码之间的依赖关系置于同一个类中,并向用户隐藏了所有不必要的细节。

然后创建你的 map 变成:

Map<String,Integer> categoryCountMap = CategoryCount.getAllCategoryCounts()
.collect(Collectors.toMap(CategoryCount::getCategory, CategoryCount::getCount));

关于java - List<Object[]> 到 Java 8 中的 Map<K, V>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35689206/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com