所以我构建了这两个类: 1.实现可比较的类型 2. GenreManager,它采用类型集合并创建它的内部副本。稍后在GenreManager中,我需要通过获取名称作为输入来添加新的类型,并且我需要为该类型分配下一个空闲ID号,这基本上是在最小的使用id之后的下一个最小正数。
我正在尝试使用Collections.sort()对我的列表进行排序,但是我收到以下错误: "没有类型变量T的实例,以便Collection符合List。"而且我不确定这是指什么...我已经尝试在这里准备了一些关于此的帖子,但无法找出解决方案......以下是代码的一部分:
public class Genre implements Comparable<Genre>{
private int id;
private String name;
public Genre(int id, String name){
this.id = Validate.requireNonNegative(id);
this.name = Validate.requireNonNullNotEmpty(name);
}
@Override
public int compareTo(Genre o) {
int res = Integer.valueOf(id).compareTo(o.id);
if (res != 0){
return res;
}
else{
return this.name.compareToIgnoreCase(o.name);
}
}
}
public class GenreManager{
private Collection<Genre> genres;
private Collection<Genre> sortedTree;
public GenreManager(){
this.genres = new ArrayList<Genre>();
}
public GenreManager(Collection<Genre> genres){
// check for duplicates
for (Genre x : genres){
for (Genre y : genres){
if (x.equals(y) || x.getName().equals(y.getName()))
throw new IllegalArgumentException("List contains duplicates");
}
}
this.genres = new ArrayList<Genre>(Collections.sort(genres));
}
}
我正在尝试在上面的构造函数中进行排序。有人能告诉我如何解决这个问题吗?
我试过玩一下,尝试将私有变量从Collection<Genre>
更改为List<Genre>
,例如类似的东西,但没有任何效果......我也试过转换.sort的输入方法(List<Genre>
),但它也没有工作。
PS:我无法更改任何方法标题或类标题。
谢谢!
答案 0 :(得分:0)
如前所述,您的代码有几个错误,使其无法使用:
自行检查元素的相等性。
Collections.sort方法将List of Comparable作为参数,当Collection在层次结构中略高时,这意味着您不能将其用作参数。要解决此问题,请将变量类型的声明更改为List。
this.genres = new ArrayList/LinkedList(genres)
Collections.sort(this.genres)
同样,您可以考虑使用TreeSet,因为它包含所有已排序且没有重复的元素,因此您的构造函数将看起来像
this.genres = new TreeSet(genres)
此外,即使在添加过程中也可以防止重复,因此如果您有10个元素,则添加已存在的元素将不会对您的集进行任何更改。但是使用这个数据结构,你应该在添加之前检查变量为null,因为它会产生NullPointerException
答案 1 :(得分:0)
根据要求,这是我对回答问题的评论的汇编:
当前问题是Collections.sort(List<T>)
采用List
参数而不仅仅是Collection
,因为通常不需要对集合进行排序(例如,散列集不是)。此外,该方法返回void
并对传递的列表进行排序,即您调用它的方式将无法编译。
考虑到所有这些因素,您的代码可能会更改为:
public class GenreManager{
private List<Genre> genres;
...
public GenreManager(Collection<Genre> genres){
...
//create a list out of the passed collection
this.genres = new ArrayList<Genre>( genres );
//sort the list
Collections.sort(this.genres);
}
}
您发布的代码的另一个问题是,对于任何非空集合,它将抛出IllegalArgumentException
因为元素与自身进行比较。在条件中添加x != y
的检查可以解决这个问题,但代码仍然有点慢,因为它的时间复杂度为O(n 2 )。
这可以解决使用集合而不是列表。但是,HashSet
取决于equals()
和hashCode()
如何定义相等性,这似乎与您的要求不符。这可以通过使用根据需要实现两种方法的包装器对象来解决。
更好的方法可能是使用TreeSet
。 TreeSet
使用比较来确定顺序和相等性(如果比较结果为0),从而允许您让Genre
类实现Comparable
,或者提供单独的Comparator
1}}(例如,如果你需要多个不同的相等定义)。
如果您只想消除重复项,那么您的代码可能如下所示:
public class GenreManager{
private SortedSet<Genre> genres;
...
public GenreManager(Collection<Genre> genres){
this.genres = new TreeSet<>( genres );
}
}
如果您想知道集合中有哪些重复项,您可以这样做:
public GenreManager(Collection<Genre> genres){
this.genres = new TreeSet<>(); //the generic type is inferred from this.genres
for( Genre element : genres ) {
//If the element didn't exist in the set add() will return true, false if it existed
boolean nonDuplicate = this.genres.add( element );
//handle the duplicate element here
}
}