我有一个列表,我需要在其中循环浏览并找到匹配项,以便将它们组合在一起并将它们添加到另一个列表中。问题是我在多次迭代某些元素或跳过某些元素方面一直遇到问题。
列表中的对象每个都有两个int值。如果第一个int值是两个元素之间的匹配,则我需要合并两个对象的第二个int值,然后将该对象添加到另一个列表中
如果我有一个列表((12,10), (13,10), (12,5), (14,5), (14,10), (10,20))
我想将12和14合并为一个新列表
((12,15), (14,15))
和我的原始列表将剩下((13,10), (10,20))
我尝试过使用带有和不带有迭代器的for循环,但是没有运气。
List<Record> finalList = new ArrayList<Record>();
for (int i = 0; i < tempAggregateList.size(); i++){
Record record = tempAggregateList.get(i);
for (int j = i+1; j < tempAggregateList.size(); j++){
Record nextRecord = tempAggregateList.get(j);
if (record.getFirstValue() == nextRecord.getFirstValue()){
record.setSecondValue(record.getSecondValue() + nextRecord.getSecondValue());
//then remove nextRecord from tempAggregateList
}
}
finalList.add(record);
}
以现在的方式,我的第一个for循环将遍历我已经合并并添加到finalList
的元素。仅仅删除我添加到finalList的元素是最容易的,但是我还没有找到一种方法。
答案 0 :(得分:3)
您应该能够使用流:
// group by first value
Map<Integer, Record> newList = list.stream().collect(Collectors.groupingBy(Record::getFirstValue,
// for each record list for the same first value, add the second one
Collectors.collectingAndThen(
// add first and second value for each pair
Collectors.reducing((r1, r2) -> new Record(r1.getFirstValue(), r1.getSecondValue() + r2.getSecondValue())),
// there will be no empty list, so all optionals will be present
Optional::get));
现在您有了一个Map<Integer, Record>
,键是第一个值,键是组合的Record
。
编辑:我意识到,这样做可以更容易
BinaryOperator<Record> addRecords = (r1, r2) -> new Record(r1.getFirstValue(), r1.getSecondValue() + r2.getSecondValue());
Map<Integer, Record> map = list.stream().collect(
toMap(Record::getFirstValue, r -> r, addRecords));
,如果您需要列表并在一行中完成
List<Record> result = list.stream().collect(
collectingAndThen(
toMap(Record::getFirstValue, r -> r, addRecords),
m -> new ArrayList<>(m.values())));
暗含从Collectors
的静态导入。
答案 1 :(得分:1)
在finalList.add(record)之后,简单地添加tempAggregateList.remove(i);
答案 2 :(得分:0)
这使用groupingBy
获得List
中的List
。如果List
的长度大于1,则将其添加到最终列表中。如果List
的长度等于1,则将其保留在原始List
中。
List<Record> originalList = new ArrayList();
originalList.add(new Record(12, 10));
originalList.add(new Record(13, 10));
originalList.add(new Record(12, 5));
originalList.add(new Record(14, 5));
originalList.add(new Record(14, 10));
originalList.add(new Record(10, 20));
List<Record> finalList = originalList.stream().collect(groupingBy(Record::getFirstValue)).values().stream().filter((t) -> {
return t.size() > 1;
}).flatMap(x -> x.stream()).collect(Collectors.toList()).stream().collect(groupingBy(Record::getFirstValue, Collectors.summingInt(Record::getSecondValue))).entrySet().stream().map(t -> new Record(t.getKey(), t.getValue())).collect(Collectors.toList());
finalList.forEach((t) -> {
System.out.println("(" + t.getFirstValue() + ", " + t.getSecondValue() + ")");
});
originalList = originalList.stream().collect(groupingBy(Record::getFirstValue)).values().stream().filter((t) -> {
return t.size() == 1;
}).flatMap(x -> x.stream()).collect(Collectors.toList()).stream().collect(groupingBy(Record::getFirstValue, Collectors.summingInt(Record::getSecondValue))).entrySet().stream().map(t -> new Record(t.getKey(), t.getValue())).collect(Collectors.toList());
originalList.forEach((t) -> {
System.out.println("(" + t.getFirstValue() + ", " + t.getSecondValue() + ")");
});
输出
(12, 15)
(14, 15)
(10, 20)
(13, 10)
答案 3 :(得分:0)
仅出于乐趣,迭代,一个Set
存储要删除的索引,以及反向迭代以从初始列表中删除项目:
public static void main(String[] args) {
List<Record> tempAggregateList = new ArrayList<Record>();
tempAggregateList.add(new Record(12, 10));
tempAggregateList.add(new Record(13, 10));
tempAggregateList.add(new Record(12, 5));
tempAggregateList.add(new Record(14, 5));
tempAggregateList.add(new Record(14, 10));
tempAggregateList.add(new Record(10, 20));
List<Record> finalList = new ArrayList<>();
Set<Integer> set = new HashSet<>();
for (int i = 0; i < tempAggregateList.size(); i++) {
if (!set.contains(i)) {
Record record = tempAggregateList.get(i);
int baseValue = record.getFirstValue();
int sum = record.getSecondValue();
boolean found = false;
for (int j = i + 1; j < tempAggregateList.size(); j++) {
Record nextRecord = tempAggregateList.get(j);
if (nextRecord.getFirstValue() == baseValue) {
found = true;
set.add(i);
set.add(j);
sum += nextRecord.getSecondValue();
}
}
if (found)
finalList.add(new Record(baseValue, sum));
}
}
for (int i = tempAggregateList.size() - 1; i >= 0; i--) {
if (set.contains(i))
tempAggregateList.remove(i);
}
for (Record r : tempAggregateList) {
System.out.print("(" + r.getFirstValue() + ", " + r.getSecondValue() + ") ");
}
System.out.println();
for (Record r : finalList) {
System.out.print("(" + r.getFirstValue() + ", " + r.getSecondValue() + ") ");
}
}
将打印:
(13, 10) (10, 20)
(12, 15) (14, 15)