Я создаю программу для подражания счету ресторана, в нем есть два класса: 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());
}
}
Фактический результат:
Пицца для пиццы
Результат, который я хотел бы:
Мороженое для пиццы
Основываясь на вашем примере приложения, похоже, вы хотите вернуть только отдельные имена элементов из 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
который возвращается.
Самый простой способ - делегировать функциональность удаления дублирования в Set
.
Для этого необходимо, чтобы методы equals()
и hashCode()
были правильно реализованы и задали Item
неизменяемый класс.
Используйте Set (реализация HashSet) вместо arraylist, который предназначен для предотвращения дублирования элементов
Мое понимание вашего вопроса заключается в том, что вы хотите сохранить список предметов для каждой закусочной, а также сохранить другой список, в котором хранятся посетители. И вы хотите удалить повторяющиеся записи. По сути, вам нужно использовать Set, а не ArrayList. Набор автоматически запретит вам хранить дубликаты во время вставки, поэтому необходимости удалить дубликат не будет. Вы можете использовать либо HashSet, либо TreeSet. Надеюсь это поможет. С уважением Сандип
В кратчайшие сроки
itemList = new ArrayList<Item>(new HashSet<Item>(itemList));
добавьте инструкцию выше перед возвратом.
А также лучшим вариантом является использование Set
#equals
и #hashCode
. Поэтому набор не сможет идентифицировать дубликаты.
getDinerItems()
? Должен ли он возвращать коллекцию товаров, в которой данный товар появляется только один раз (с разными «счетчиками покупателя»), или он должен возвращать только товары, которые появляются один раз в списках товаров всех посетителей? Последнее - то, что на самом деле подразумевает ваш вопрос (что на самом деле не имеет смысла).