Remove an object from an ArrayList given only one attribute

末鹿安然 提交于 2021-02-07 12:51:36

问题


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.

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

回答1:


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.

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

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

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

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

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

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.

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.




回答2:


Do you want to remove an object at a specific index? I'm not entirely sure what you mean by 'number field'. If so, jump to method: remove(int):

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

EDIT: If you want to find/adjust a field of an object in the Array list, you can do this (piece of my own code):

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

All you have to do is iterate through the list, and search through the field that you want to find. Then use the remove(int) method.




回答3:


simply use the remove function of ArrayLists in Java:

theNameOfYourArrayList.remove(ItemNumber);

to remove the element which has the index (int ItemNumber)

to check if the element with item number (int ItemNumber) exists in your ArrayList (hypothetically called theNameOfYourArrayList):

theNameOfYourArrayList.get(ItemNumber);



回答4:


I'm going to assume that by 'number field' you mean that you invoked ArrayList with the Integer data type. I have a few different solutions to your problem:

  1. ArrayLists, assuming that the ArrayList is ArrayList<Integer> numList = new ArrayList<Integer>(); you can simply write a method that will search 'numList' and delete the index that the number is. The problem is, contains and find in ArrayLists can be slow.

    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 are a handy data type that is like an ArrayList, except, its data is its 'index' (sortof). I won't go in depth about how they work, but I will say that searching in them is considered O(1). This will make your deletion really easy, and fast. Note: the HashSet assumes there are no duplicate numbers, if there are use a HashMap.

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


For more information on HashMaps, HashSets and ArrayLists, see: http://docs.oracle.com/javase/8/docs/api/



来源:https://stackoverflow.com/questions/29153764/remove-an-object-from-an-arraylist-given-only-one-attribute

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!