我已经为用户定义的类实现了一个有序集,并且还使用Comparable接口将compareTo方法实现到用户定义的类。现在我的要求是,如果一个字符(即a到z)已经存在,那么增加字符的频率,然后根据它们的频率对输入进行排序。
String s = "abc"; // or "aaaab" or any set of string between [ a - z ]
SortedSet<FreequencyIndex> sortedSet = new TreeSet<FreequencyIndex>();
FreequencyIndex symbol;
for(int index = s.length() - 1; index >=0 ; index--){
symbol = new FreequencyIndex(s.charAt(index), index, 0);
sortedSet.add(symbol);
}
System.out.println(sortedSet);
用户定义的类:
class FreequencyIndex implements Comparable<FreequencyIndex>{
char symbol;
int index;
int frequency;
public FreequencyIndex(char newSymbol, int newIndex, int newFrequency){
this.symbol = newSymbol;
this.index = newIndex;
this.frequency = newFrequency;
}
@Override
public String toString(){
return this.symbol + " "+ this.frequency;
}
@Override
public int compareTo(FreequencyIndex f2){
if(this.symbol == f2.symbol){
f2.frequency++;
return 0;
}
else
if(this.frequency > f2.frequency)
return 1;
else
return -1;
}
}
我在这里缺少什么,有人可以解释一下吗?
答案 0 :(得分:1)
SortedSet
是一种具有某种排序的集合,最臭名昭着的是TreeSet
。但是,在调用add
时,排序对于确定节点是否已经存在也很重要。因此,您使用与符号不同的东西进行排序的解决方案会破坏它。
此外,当您向任何类型的集合添加内容时,无论是TreeSet
,HashSet
还是几乎任何其他集合,您都不应该修改对象,或者至少是它的字段用于比较。这意味着,如果您以某种方式更改对象,equals
,compareTo
或hashCode
等方法仍应返回相同的值,否则您的设置无法正常工作,甚至可以导致重复出现。
在您的情况下,最干净的解决方案是不要将FrequencyIndex
用作任何关键字,并使用Map<Character, FrequencyIndex>
进行符号搜索。除非在添加新元素的过程中多次需要排序集,否则您可以在完成频率检查后对其进行排序,以下代码可以使用Java 8流轻松地使用所述映射进行排序:
map.values().stream()
.sorted(Comparator.comparing(FrequencyIndex::getFrequency))
.collect(Collectors.toList());
上面提到的频率吸气剂 - 我认为你应该将吸气剂添加到FrequencyIndex类。
效率可能实际上更好 - 在频率检查期间没有重新排序,并且与输入大小相比,它只在一个相当小的集合上完成一次。