繁体   English   中英

只给出一个属性,从ArrayList中删除一个对象

[英]Remove an object from an ArrayList given only one attribute

我有一个项目的ArrayList,我希望能够通过只输入一个Item属性从列表中删除一个Item,例如它的数字(int ItemNumber)。 当我检查物品数量时,我也想做同样的事情。

这些是我的equals()contains()方法,我需要在这里进行任何更改吗?

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()代码,您将无法更改比较属性。

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

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

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

class Item {
    final int num;
    final String name;

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

给定一个List<Item>称为itemsint变量叫number ,表示要删除的项数,你可以简单地做:

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

如果您无法使用Java 8 ,则可以使用自定义比较器,二进制搜索和虚拟对象来实现此目的。

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

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);
    }
}

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

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);
}

例如,要搜索名称等其他字段,您需要创建名称比较器并使用它来对列表中的二进制搜索进行排序和运行。

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

是否要删除特定索引处的对象? 我不完全确定'数字字段'是什么意思。 如果是这样,跳转到方法:remove(int):

http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#remove%28int%29

编辑:如果你想在数组列表中找到/调整对象的字段,你可以这样做(我自己的代码片段):

public boolean studentHasISBN(ArrayList<Student> st, String s){
    for(Student j : st) {
        if(s.equals(j.getRentedBookISBN()))
            return true;
    }
    return false;
}

您所要做的就是遍历列表,并搜索您要查找的字段。 然后使用remove(int)方法。

只需在Java使用ArrayListsremove函数:

theNameOfYourArrayList.remove(ItemNumber);

删除具有索引的元素(int ItemNumber)

检查具有项目编号(int ItemNumber)的元素是否存在于ArrayList (假设名为theNameOfYourArrayList ):

theNameOfYourArrayList.get(ItemNumber);

我将假设“数字字段”表示您使用Integer数据类型调用ArrayList。 我有几个不同的解决方案来解决你的问题:

  1. ArrayLists,假设ArrayList是ArrayList<Integer> numList = new ArrayList<Integer>(); 你可以简单地编写一个方法来搜索'numList'并删除该数字所在的索引。 问题是,在ArrayLists中包含和查找可能很慢。

    public void deleteNumField(int field) { // this will stop any error if field isn't actually in numList // and it will remove the first index of field in the ArrayList if(numList.contains(field)) numList.remove(numList.find(field)); }

  2. HashSets,HashSets是一种方便的数据类型,类似于ArrayList,除了它的数据是它的'索引'(sortof)。 我不会深入探讨它们是如何工作的,但我会说在其中搜索被认为是O(1)。 这将使您的删除非常简单,快速。 注意:如果使用HashMap,HashSet假定没有重复的数字。

    HashSet<Integer> numList = new HashSet<Integer>(); public void deleteNumField(int field) { // this will stop errors from attempting to remove a // non-existant element, and remove it if it exists. if(numList.contains(field)) numList.remove(field); }


有关HashMaps,HashSets和ArrayLists的更多信息,请参阅: http ://docs.oracle.com/javase/8/docs/api/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM