我试图实现一个按照这样的添加次数排序的Set:
public class App {
public static void main(String args[]) {
FrequencyOrderedTreeSet<String> set = new FrequencyOrderedTreeSet<String>();
set.add("bar");
set.add("foo");
set.add("foo");
Iterator<String> i = set.iterator();
while (i.hasNext()) {
System.out.print(i.next());
}
// prints "foobar"
}
}
我创建了protected class FrequencyOrderedTreeSet.Element
,其中Comparable
实施T entry
和int frequency
属性,TreeSet<FrequencyOrderedTreeSet.Element>
扩展FrequencyOrderedTreeSet<T>
并覆盖了compareTo
上的equals
和Element
方法。
一个问题是由于类型擦除问题我无法覆盖add()方法,而且我无法在instanceof Element
方法中调用equals
,因为以防万一赋予它的对象是一个元素,我必须比较它们的条目,但如果它不是,我必须将对象本身与this.entry
进行比较。
在add
方法中,我创建一个新元素,找到集合中具有相同条目的元素,将新元素的频率设置为&#34; old + 1&#34;,删除旧元素一个并添加新的。我甚至不确定这是做到这一点的最佳方式,还是因为我描述的其他问题也能起作用。
问题是:实现此类数据结构的最佳方式是什么?如果我以某种方式走上正轨 - 我怎样才能规避上面提到的问题?
答案 0 :(得分:1)
这是一个基本的实现。它不是最优的,如果你想实现完整的Set接口,还需要做更多的工作。
public class FrequencySet<T> implements Iterable<T>
{
private TreeSet<T> set;
private HashMap<T, Integer> elements = new HashMap<T, Integer>();
public FrequencySet()
{
set = new TreeSet<T>(new Comparator<T>()
{
public int compare(T o1, T o2)
{
return elements.get(o2)-elements.get(o1);
}
});
}
public void add(T t)
{
Integer i = elements.get(t);
elements.put(t, i == null ? 1 : i+1);
set.remove(t);
set.add(t);
}
public Iterator<T> iterator() {return set.iterator();}
public static void main(String [] args)
{
FrequencySet<String> fset = new FrequencySet<String>();
fset.add("foo");
fset.add("bar");
fset.add("foo");
for (String s : fset)
System.out.print(s);
System.out.println();
fset.add("bar");
fset.add("bar");
for (String s : fset)
System.out.print(s);
}
}
关键在于add方法。我们更改给定对象的计数器(更改关系顺序),将其从支持集中删除并将其重新放入。
答案 1 :(得分:1)
这是另一种方式(使用GET时计数增加)
@SuppressWarnings("rawtypes")
final class Cache implements Comparable {
private String key;
private String value;
private int counter;
public String getValue() {
counter++;
return value;
}
private void setValue(String value) { this.value = value; }
public String getKey() { return key; }
private void setKey(String key) { this.key = key; }
public int getCounter() { return counter; }
public void setCounter(int counter) { this.counter = counter; }
public Cache(String key, String value) {
this.setKey(key);
this.setValue(value);
setCounter(0);
}
@Override
public int compareTo(Object arg0) {
if(!(arg0 instanceof Cache)) {
throw new ClassCastException();
}
return this.getCounter() - ((Cache) arg0).getCounter();
}
}