gpt4 book ai didi

Java Arraylist 想要合并具有相同属性值的对象
转载 作者:行者123 更新时间:2023-11-30 08:12:22 25 4
gpt4 key购买 nike

Java ArrayList,填充了称为 packinglistrows 的对象,其中包含三个键值(ISBN、PalletNumber、Quantity)以及其他属性。

我有这个 ArrayList,其中包含所有相同的 ISBN 值。我希望能够合并具有相同 PalletNumbers 数量值的项目。

例如:

ArrayList items = [ packinglistrow( 1234, 1, 10 ), packinglistrow( 1234, 2, 5), packinglistrow( 1234, 1, 15 ) ]

合并后 [0] 和 [2] 对象被合并,因为它们具有相同的 ISBN 和托盘编号 1。导致合并对象具有更新的数量:

ArrayList items = [ packinglistrow( 1234, 1, 25 ), packinglistrow( 1234, 2, 5) ]

是否正在考虑循环并比较不同类型并将其添加到新的 ArrayList,然后循环并合并,但必须有更简洁的方法来完成此操作吗?

谢谢。

最佳答案

首先创建一个类来处理这些数据。有两点需要注意。 equals 和 hashcode 方法仅基于 isbnpalletNumber值,并且有一个 merge返回 PackingListRow 的新实例的方法用这个和你作为参数给出的另一个实例之间的数量。

class PackingListRow {
private final String isbn;
private final int palletNumber;
private final int quantity;

public PackingListRow(String isbn, int palletNumber, int quantity) {
this.isbn = isbn;
this.palletNumber = palletNumber;
this.quantity = quantity;
}

public String getIsbn() {
return isbn;
}

public int getPalletNumber() {
return palletNumber;
}

public int getQuantity() {
return quantity;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PackingListRow that = (PackingListRow) o;
return Objects.equals(palletNumber, that.palletNumber) &&
Objects.equals(isbn, that.isbn);
}

@Override
public int hashCode() {
return Objects.hash(isbn, palletNumber);
}

@Override
public String toString() {
return "PackingListRow{" +
"isbn='" + isbn + '\'' +
", palletNumber=" + palletNumber +
", quantity=" + quantity +
'}';
}

public PackingListRow merge(PackingListRow other) {
assert(this.equals(other));
return new PackingListRow(this.isbn, this.palletNumber, this.quantity + other.quantity);
}
}

完成后,您只需创建另一个最初为空的新列表。它将包含合并值。对于初始列表中的每个实例,您检查它是否已经在合并列表中。如果是,则通过调用 merge 修改现有实例,否则只需将其附加到列表中。我们最终得到以下算法:

List<PackingListRow> list =
Arrays.asList(new PackingListRow("1234", 1, 10), new PackingListRow("1234", 2, 5), new PackingListRow("1234", 1, 15));

List<PackingListRow> mergedList = new ArrayList<>();
for(PackingListRow p : list) {
int index = mergedList.indexOf(p);
if(index != -1) {
mergedList.set(index, mergedList.get(index).merge(p));
} else {
mergedList.add(p);
}
}

System.out.println(mergedList);

哪些输出:

[PackingListRow{isbn='1234', palletNumber=1, quantity=25}, PackingListRow{isbn='1234', palletNumber=2, quantity=5}]

对于 Java 8,我可能会使用不同的策略(至少你表明有多种方法可以解决问题)。我会创建一个静态类来为我进行分组:

class PackingListRow {
private final String isbn;
private final int palletNumber;
private final int quantity;

static class GroupPacking {

private final String isbn;
private final int palletNumber;

public GroupPacking(PackingListRow p) {
this.isbn = p.isbn;
this.palletNumber = p.palletNumber;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GroupPacking that = (GroupPacking) o;
return Objects.equals(palletNumber, that.palletNumber) &&
Objects.equals(isbn, that.isbn);
}

@Override
public int hashCode() {
return Objects.hash(isbn, palletNumber);
}
}

....

public PackingListRow merge(PackingListRow other) {
assert (new GroupPacking(other).equals(new GroupPacking(this)));
return new PackingListRow(this.isbn, this.palletNumber, this.quantity + other.quantity);
}
}

然后你就可以使用 Stream API 了。给定原始列表,您会得到一个 Stream<PackingListRow>您可以根据元素的 GroupPacking 实例(键)从中将元素收集到 Map 中。该值只是当前的 PackingListRow实例。如果您有两个具有相同 GroupPacking 值的实例(根据 equals/hashcode),则合并它们。你终于得到了values() map 的。

List<PackingListRow> mergedList =
new ArrayList<>(list.stream().collect(toMap(PackingListRow.GroupPacking::new, p -> p, PackingListRow::merge)).values());

关于Java Arraylist<Object> 想要合并具有相同属性值的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30547105/

25 4 0