Удаление повторяющихся объектов из ArrayList

1

Я создаю программу для подражания счету ресторана, в нем есть два класса: Diner и Food Item.

Класс предмета:

package dinersbill;

public class Item {

    private String name;
    private double price;
    private int buyerCount = 0;

    public Item(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }

    public int getBuyerCount() {
        return buyerCount;
    }

    public void incrementBuyerCount() {
        buyerCount += 1;
    }

}

Класс Diner:

package dinersbill;

import java.util.ArrayList;

public class Diner {

    private String name;
    private ArrayList<Item> itemList = new ArrayList<Item>();

    public Diner(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public ArrayList<Item> getItemList() {
        return itemList;
    }

    public void addItem(Item foodItem) {
        itemList.add(foodItem);
        foodItem.incrementBuyerCount();
    }

    public double getPrice() {
        double total = 0;
        for(Item item : itemList) {
            total += item.getPrice() / item.getBuyerCount();
        }
        return total;
    }

}

Класс Diner содержит объекты ArrayList объектов, поскольку один Diner может приобретать несколько элементов. Наконец, у меня есть класс верхнего уровня, который содержит объекты ArrayList Diner:

package dinersbill;

import java.util.ArrayList;

public class DinerList {

    private ArrayList<Diner> diners = new ArrayList<Diner>();

    public DinerList(ArrayList<Diner> diners) {
        this.diners = diners;
    }

    public ArrayList<Item> getDinerItems() {
        ArrayList<Item> itemList = new ArrayList<>();
        for(Diner d : diners) {
            for(Item i : d.getItemList()) itemList.add(i);
        }
        return itemList;
    }

} 

Как я могу изменить метод getDinerItems в DinerList только для возврата объектов, если они появляются один раз? У меня возникла проблема с элементами, появляющимися более одного раза в этом списке, поскольку один элемент может быть куплен несколькими Diners.

Например:

private static DinerList diners = new DinerList(dinerList);

public static void main(String[] args) {
    Diner diner1 = new Diner("John");
    Diner diner2 = new Diner("Tom");

    dinerList.add(diner1);
    dinerList.add(diner2);

    Item item1 = new Item("Pizza", 5);
    Item item2 = new Item("Icecream", 10);

    diner1.addItem(item1);
    diner2.addItem(item1);
    diner2.addItem(item2);

    for(Item i : diners.getDinerItems()) {
        System.out.println(i.getName());
    }


}

Фактический результат:

Пицца для пиццы

Результат, который я хотел бы:

Мороженое для пиццы

  • 0
    Читайте о множествах .
  • 0
    Не могли бы вы уточнить, что должен делать getDinerItems() ? Должен ли он возвращать коллекцию товаров, в которой данный товар появляется только один раз (с разными «счетчиками покупателя»), или он должен возвращать только товары, которые появляются один раз в списках товаров всех посетителей? Последнее - то, что на самом деле подразумевает ваш вопрос (что на самом деле не имеет смысла).
Показать ещё 1 комментарий
Теги:
object
arraylist

5 ответов

1
Лучший ответ

Основываясь на вашем примере приложения, похоже, вы хотите вернуть только отдельные имена элементов из getDinerItems(). Если это так, просто измените метод на

public Set<String> getDinerItems() {
  Set<String> itemNames = new HashSet<String>();
  for (Diner d : diners) {
    for (Item i : d.getItemList()) {
      itemNames.add(i.getName());
    }
  }
  return itemNames;
}

Однако, если покупатель имеет значение для вас (и, вероятно, они это делают), вам также нужны изменения в классе Diner:

Вам необходимо перепроектировать свой класс Diner чтобы он мог удерживать только один Item с заданным именем (при условии, что "имя" однозначно идентифицирует элемент, и все элементы с тем же именем имеют одинаковую цену в вашей модели домена). Это потребует изменения коллекции предметов в Diner на Map:

private Map<String, Item> items = new HashMap<String, Item>();

Вам также нужно изменить логику в addItem() следующим образом:

public void addItem(Item foodItem) {

    if (!items.contains(foodItem.getName())) {
      items.put(foodItem.getName(), foodItem);          
    }
    items.get(foodItem.getName()).incrementBuyerCount();
}

Наконец, в getDinerItems() вы суммируете количество покупателей всех предметов diners в набор Item который возвращается.

2

Самый простой способ - делегировать функциональность удаления дублирования в Set.

Для этого необходимо, чтобы методы equals() и hashCode() были правильно реализованы и задали Item неизменяемый класс.

2

Используйте Set (реализация HashSet) вместо arraylist, который предназначен для предотвращения дублирования элементов

1

Мое понимание вашего вопроса заключается в том, что вы хотите сохранить список предметов для каждой закусочной, а также сохранить другой список, в котором хранятся посетители. И вы хотите удалить повторяющиеся записи. По сути, вам нужно использовать Set, а не ArrayList. Набор автоматически запретит вам хранить дубликаты во время вставки, поэтому необходимости удалить дубликат не будет. Вы можете использовать либо HashSet, либо TreeSet. Надеюсь это поможет. С уважением Сандип

0

В кратчайшие сроки

itemList = new ArrayList<Item>(new HashSet<Item>(itemList));

добавьте инструкцию выше перед возвратом.

А также лучшим вариантом является использование Set

  • 0
    Я не думаю, что это что-то изменит, потому что его классы моделей не переопределяют #equals и #hashCode . Поэтому набор не сможет идентифицировать дубликаты.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню