T. *_*hdi 2 java collections java-8 java-stream
假设一个 Person 类:
public class Person {
private String name;
private int amount;
}
Run Code Online (Sandbox Code Playgroud)
并假设一个 Person 集合:
persons = [{"Joe", 5}, {"Joe", 8}, {"Joe", 10}, {"Jack", 3}, {"Jack",6}, {"Joe" 4},
{"Joe", 7}, {"Jack", 12}, {"Jack", 15}, {"Luke", 10}, {"Luke", 12}]
Run Code Online (Sandbox Code Playgroud)
我想要的是获取具有相同名称且相互跟随的合并元素的人员列表并求和(使用java 8 Stream);像这样的列表:
Perons = [{"Joe", 23}, {"Jack", 9}, {"Joe", 11}, {"Jack", 27}, {"Luke", 22}]
Run Code Online (Sandbox Code Playgroud)
您应该Collector为此创建自己的自定义。
class AdjacentNames {
List<Person> result = new ArrayList<>();
Person last = null;
void accumulate(Person person) {
if (last != null && last.getName().equals(person.getName())) {
last.setAmount(last.getAmount() + person.getAmount())
} else {
last = new Person(person.getName(), person.getAmount()); // Clone
result.add(last);
}
}
AdjacentNames merge(AdjacentNames other) {
List<Person> other_list = other.finisher();
if (other_list.size() > 0) {
accumulate(other_list.remove(0));
result.addAll(other_list);
last = result.get(result.size()-1);
}
return this;
}
List<Person> finisher() {
return result;
}
public static Collector<Person, AdjacentNames, List<Person>> collector() {
return Collector.of(AdjacentNames::new,
AdjacentNames::accumulate,
AdjacentNames::merge,
AdjacentNames::finisher);
}
}
Run Code Online (Sandbox Code Playgroud)
并使用如下:
List<Person> result = persons.stream().collect(AdjacentNames.collector());
Run Code Online (Sandbox Code Playgroud)