在Kotlin(或Java)中创建新的ArrayList并对相同项目求和的最有效方法是什么



示例假设我有一个数据类:

data class MyList(
val username :String,
val correctQuestions :Int
)

然后是这样的ArrayList:

var myList = ArrayList<MyList>()

myList现在填充了许多值,例如:

myList.add(MyList("@Frank68", 54))

用户名可能存在多次

现在,创建一个MyList类型的新ArrayList最有效的方法是什么,它将显示每个用户名的所有正确问题?当然,在新创建的ArrayList中,每个用户名应该只存在一次。

p.S.(我已经更新了我的问题,使其看起来更现实,尽管这是一个在脑海中输入最少的问题,以便更容易重现

我给你一个直截了当的答案,将忽略"最有效的";现在有一点。当在这个代码中遇到瓶颈时,可以问一个后续问题。

转换为查找结构,计算总和,然后再次转换为列表:

Map<MyList, Integer> lookup = new HashMap<>();
for (var item : list) {
lookup.computeIfAbsent(item.name, n -> new MyList(name, 0)).correctQuestions += item.correctQuestions;
}
List<MyList> sums = lookup.values();

您还可以使用流和groupingBy收集器:

List<MyList> sums = list.stream()
.collect(Collectors.groupingBy(
l -> l.name,
Collectors.summingInt(l -> l.correctQuestions)))
.entrySet()
.stream()
.map(e -> new MyList(e -> e.getKey(), e -> e.getValue()))
.collect(Collectors.toList());

输入:

List.of(new MyList("a", 1), new MyList("b", 2), new MyList("a", 3));

输出:

a -> 4
b -> 2

这里有一个双线Kotlin解决方案。按名称分组以获取名称到关联数据列表的映射。然后映射这些条目并求和它们的整数属性。

myList.groupBy(MyList::username)
.map { (name, values) -> MyList(name, values.sumBy(MyList::correctQuestions)) }

如果你真的需要它在一个可变列表中(你指定了ArrayList(,你可以这样做:

myList.groupBy(MyList::username)
.asSequence()
.map { (name, values) -> MyList(name, values.sumBy(MyList::correctQuestions)) }
.toMutableList()

您可以将StreamgroupingBy收集器一起用于以下用途:

Map<String, List<MyList>> map = myList.stream()
.collect(Collectors.groupingBy(MyList::getName));

现在您有了一个Map,它以name为键,所有MyList对象都以特定的name为值。

试试这个。

List<MyList> mylist = List.of(
new MyList("A", 2),
new MyList("B", 3),
new MyList("B", 1));
List<MyList> result = mylist.stream()
.collect(Collectors.groupingBy(e -> e.name, Collectors.summingInt(e -> e.correctQuestions)))
.entrySet().stream()
.map(e -> new MyList(e.getKey(), e.getValue()))
.collect(Collectors.toList());
System.out.println(result);

输出:

[MyList(A, 2), MyList(B, 4)]

Kotlin一行:

myList.groupingBy { it.name }
.fold(0, { acc, it ->  acc + it.correctQuestions})
.map { e -> MyList(e.key, e.value) }

最新更新