当前位置: 首页 > 知识库问答 >
问题:

使用集合时。排序-不存在变量T的实例,因此集合符合等

楮自珍
2023-03-14

所以我建立了两个类:1。实现可比2的类型。流派管理器,它获取流派集合并创建其内部副本。在GenerManager的后面,我需要通过输入一个名字来添加新的类型,我需要给这个类型分配下一个自由id号,基本上是最小使用id后的下一个最小正数。

我试图使用Collections.sort()排序我的列表,但我得到以下错误:没有实例类型变量T存在,以便集合符合列表...我试着准备了一堆关于这个的帖子,但没能找到解决方案...下面是部分代码:

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更改私有变量

PS:我不能更改任何方法头或类头。

谢谢


共有2个答案

卫弘懿
2023-03-14

如前所述,您的代码有几个错误,使其无法使用:

>

  • 检查元素本身是否相等。

    收藏。当集合在层次结构中稍高一些时,sort方法将Comparable列表作为参数,这意味着不能将其用作参数。要解决此问题,请将变量类型的声明更改为列表。

    这个。流派=新的ArrayList/LinkedList(流派)集合。排序(this.genres)

    同样,您可以考虑使用TreeSet,因为它保存所有排序且没有重复的元素,因此您的构造函数看起来就像

    这个。类型=新树集(类型)

    此外,它甚至在添加过程中也可以防止重复,因此,如果您有10个元素,添加现有的元素不会对集合进行任何更改。但是使用这种数据结构,在添加之前应该检查变量是否为null,因为它会产生NullPointerException

  • 鲜于温书
    2023-03-14

    根据要求,以下是我回答问题的评论汇编:

    眼前的问题是集合。排序(列表)

    考虑到所有这些,您的代码可能会更改为这样的内容:

    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(n2)。

    这可以通过使用集合而不是列表来解决。然而,HashSet将取决于equals()hashCode()如何定义相等,这似乎不符合您的要求。这可以通过使用一个包装器对象来解决,该对象可以根据需要实现这两种方法。

    不过,更好的方法可能是使用树集TreeSet使用比较来确定顺序和相等性(如果比较结果为0),从而允许您要么让类型类像您那样实现可比,要么提供一个单独的比较器(例如,如果您需要多个不同的相等性定义)。

    如果您只想消除重复,那么您的代码可以如下所示:

    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
      }
    }
    

     类似资料: