我想创建一个存储相同类型对象的列表,例如:
class Card {
String title;
int point;
public Card(String t, int p) {
title = t;
point = p;
}
}
我在列表中添加了一些对象:
list.add(new Card("Fred",3));
list.add(new Card("Fred",1));
list.add(new Card("Luke",5));
list.add(new Card("John",3));
我该如何完成以下任务? 创建一个新列表,其中包含以前的元素,但每个标题一次,并计算它们的出现次数。例如:
Fred 2
Luke 1
John 1
我可以做第一部分,我只是制作一个HashSet,并覆盖歌曲的等号'和' hashCode'方法。但我不想完全删除两个具有相同标题的内容。
答案 0 :(得分:0)
Map<String, Card> cardsByTitle = new TreeMap<>();
void add(String title, int point) {
Card card = cardsByTitle.get(title);
if (card == null) {
card = new Card(title, point);
cardsByTitle.put(title, point);
} else {
card.point += point;
}
}
for (Card card : cardsByTitle.values) { }
或类似的东西。 TreeMap(即i.o.HashMap)保持标题的排序。
答案 1 :(得分:0)
您可以实现自己的List,它在ElementList内部存储其元素,并保留具有给定标题的Cards数量的Map:
public static class CountingList extends AbstractList<Card>{
private final List<Card> list;
private final Map<String, Integer> counterMap;
public CountingList() {
this(10);
}
public CountingList(Collection<? extends Card> c) {
this(c.size());
addAll(c);
}
public CountingList(int initialCapacity) {
super();
this.list = new ArrayList<>(initialCapacity);
this.counterMap = new HashMap<>(initialCapacity);
}
@Override
public boolean add(Card e) {
Integer count = counterMap.get(e.title);
String key = e.title;
if (count == null) {
list.add(e);
count = 0;
}
counterMap.put(key, ++count);
return count == 1;
}
@Override
public void add(int index, Card element) {
throw new UnsupportedOperationException();
}
@Override
public Card remove(int index) {
throw new UnsupportedOperationException();
}
@Override
public Card get(int index) {
return list.get(index);
}
@Override
public int size() {
return list.size();
}
public int getNumberOfCards(int index){
return getNumberOfCards(list.get(index).title);
}
public int getNumberOfCards(String title){
Integer count = counterMap.get(title);
return count == null ? 0 : count;
}
@Override
public String toString() {
StringBuilder b = new StringBuilder();
b.append('[');
for (Card c : this) {
b.append(c.title).append('(').append(getNumberOfCards(c.title)).append(')');
}
b.append(']');
return b.toString();
}
}
然后您可以像这样使用此列表:
public static void main(String[] args) {
List<Card> list = new ArrayList<>();
list.add(new Card("Fred",3));
list.add(new Card("Fred",1));
list.add(new Card("Luke",5));
list.add(new Card("John",3));
CountingList countingList = new CountingList(list);
System.out.println(countingList);
countingList.add(new Card("Tom", 1));
countingList.add(new Card("Tom", 10));
countingList.add(new Card("Tom", 15));
System.out.println(countingList);
countingList.add(new Card("Fred", 4));
System.out.println(countingList);
}
请注意,此List尚不支持在给定索引处插入元素和删除元素。
要获取具有给定标题的卡片数量,您可以调用CountingList#getNumberOfCards。