从仅给定一个属性的 ArrayList 中删除对象

从仅给定一个属性的 ArrayList 中删除对象

问题描述:

我有一个 Items ArrayList,我希望能够通过仅输入一个 Item 属性(例如其编号 (int ItemNumber))从列表中删除一个 Item.我也想在检查商品数量时做同样的事情.

I have an ArrayList of Items and I want to be able remove one Item from the list by entering only one Item attribute, for example its number (int ItemNumber). I also wanna do the same when I check Item quantities.

这些是我的 equals() &contains() 方法,我需要在这里做任何改变吗?

These are my equals() & contains() methods, do I need to make any changes here?

public boolean contains(T anEntry) {
    boolean found = false;
    for (int index = 0; !found && (index < numberOfEntries); index++) {
    if (anEntry.equals(list[index])) 
        found = true;
    }//end for
    return found;
} // end contains

public boolean equals(Object object){
    Item item = (Item) object;
    if (itemNo == item.itemNo)
        return true;
    return false;
}

如果改变类 Item equals()compareTo() 方法,以便它们只检查一个对象字段,例如 quantity,这可能会导致应用程序其他部分出现奇怪的行为.例如,具有不同 itemNoitemNameitemPrice 但数量相同的两个项目可以被认为是相等的.此外,如果不每次都更改 equals() 代码,您将无法更改比较属性.

If you change the class Item equals() and compareTo() methods, so that they check only one object field, such as a quantity, it could result in strange behavior in other parts of your application. For example, two items with different itemNo, itemName, and itemPrice, but with the same quantities could be considered equal. Besides, you wouldn't be able to change the comparison attribute without changing the equals() code every time.

此外,创建自定义contains() 方法没有意义,因为它属于ArrayList 类,而不属于Item.

Also, creating a custom contains() method makes no sense, since it belongs to the ArrayList class, and not to Item.

如果您可以使用 Java 8,一个干净的方法是使用新的 CollectionremoveIf 方法:

If you can use Java 8, a clean way to do it is to use the new Collection's removeIf method:

假设您有一个带有 numname 属性的 Item 类:

Suppose you have an Item class with the num and name properties:

class Item {
    final int num;
    final String name;

    Item(int num, String name) {
        this.num = num;
        this.name = name;
    }
}

给定一个名为 itemsList 和一个名为 numberint 变量,表示您要删除的项目,您可以简单地执行以下操作:

Given a List<Item> called items and an int variable called number, representing the number of the item you want to remove, you could simply do:

items.removeIf(item -> item.num == number);

如果您无法使用 Java 8,您可以通过使用自定义比较器、二进制搜索和虚拟对象来实现这一点.

If you are unable to use Java 8, you can achieve this by using custom comparators, binary search, and dummy objects.

您可以为需要查找的每个属性创建一个自定义比较器.num 的比较器如下所示:

You can create a custom comparator for each attribute you need to look for. The comparator for num would look like this:

class ItemNumComparator implements Comparator<Item> {
    @Override
    public int compare(Item a, Item b) {
        return (a.num < b.num) ? -1 : ((a.num == b.num) ? 0 : 1);
    }
}

然后您可以使用比较器对列表中的所需元素进行排序和搜索:

Then you can use the comparator to sort and search for the desired elements in your list:

public static void main(String[] args) {
    List<Item> items = new ArrayList<>();
    items.add(new Item(2, "ball"));
    items.add(new Item(5, "cow"));
    items.add(new Item(3, "gum"));

    Comparator<Item> itemNumComparator = new ItemNumComparator();
    Collections.sort(items, itemNumComparator);

    // Pass a dummy object containing only the relevant attribute to be searched
    int index = Collections.binarySearch(items, new Item(5, ""), itemNumComparator);
    Item removedItem = null;
    // binarySearch will return -1 if it does not find the element.
    if (index > -1) {
        // This will remove the element, Item(5, "cow") in this case, from the list
        removedItem = items.remove(index);
    }
    System.out.println(removedItem);
}

例如,要搜索名称等其他字段,您需要创建一个名称比较器,并使用它对列表进行排序和运行二分搜索.

To search for another field like name, for example, you would need to create a name comparator and use it to sort and run the binary search on your list.

请注意,此解决方案有一些缺点.除非您完全确定列表自上次排序后没有更改,否则您必须在运行 binarySearch() 方法之前对其重新排序.否则,它可能无法找到正确的元素.排序复杂度是 O(nlogn),因此根据列表的大小,多次运行它会变得非常昂贵.

Note this solution has some drawbacks though. Unless you are completely sure that the list didn't change since the last sort, you must re-sort it before running the binarySearch() method. Otherwise, it may not be able to find the correct element. Sorting complexity is O(nlogn), so running it multiple times can get quite expensive depending on the size of your list.