使用Collections.sort时-不存在变量T的实例,因此Collection符合等 [英] When using Collections.sort - no instance of Variable T exist so that Collection conforms etc

查看:657
本文介绍了使用Collections.sort时-不存在变量T的实例,因此Collection符合等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我建立了这两个类: 1.实现可比性的体裁 2. GenreManager,它接受一个流派的集合并创建其内部副本.稍后在GenreManager中,我将需要通过获取名称作为输入来添加新的流派,并且需要为该流派分配下一个免费ID号,这基本上是在最小的已使用ID之后的下一个最小的正数.

so I've build these two classes: 1. Genre which implements Comparable 2. GenreManager which takes a Collection of genres and creates an internal copy of it. Later in GenreManager, I will need to add new Genres by getting a name as an input, and I need to assign this Genre the next free id number, which is basically the next smallest positive number after the smallest used id.

我正在尝试使用Collections.sort()对列表进行排序,但是出现以下错误: 不存在类型变量T的实例,因此Collection符合List."而且我不确定这是指什么...我已经在这里尝试过很多关于此的文章,但无法找出解决方案...这是代码的一部分:

I am trying to use Collections.sort() to sort my list but I am getting the following error: "no instance(s) of type variable(s) T exist so that Collection conforms to List." and I am not sure what this is referring to... I've tried ready a bunch of posts about this on here but couldn't figure out the solution... Here is part of the code:

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

我正在尝试在上面的构造函数中进行排序.有人可以告诉我如何解决这个问题吗?

I am trying to do the sorting in the constructor above. Can someone tell me how to go around this?

我尝试了一些操作,例如尝试将私有变量从Collection<Genre>更改为List<Genre>,并且进行了类似的操作,但无济于事...我还尝试将.sort方法的输入强制转换为(List<Genre>),但它也不起作用.

I tried playing around a little bit, trying to change the private variable from Collection<Genre> to List<Genre> for example and similar things but nothing worked... I also tried casting the input of the .sort method to (List<Genre>) but it didn't work either.

PS:我无法更改任何方法标头或类标头.

PS: I can't change any of the method header or class headers.

谢谢!

推荐答案

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

As per request, here's a compilation of my comments to answer the question:

直接的问题是,Collections.sort(List<T>)接受一个List参数,而不仅仅是一个Collection,因为一般而言,集合不必是可排序的(例如,哈希集不是必需的).另外,该方法返回void并将传递的列表排序到位,即您调用它的方式将不会编译.

The immediate problem is that Collections.sort(List<T>) takes a List parameter and not just a Collection because collections in general don't have to be sortable (e.g. hash sets aren't). Additionally the method returns void and sorts the passed list in place, i.e. the way you call it won't compile.

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

Taking all this into consideration your code might be changed to something like this:

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 ).

The other problem with the code you posted is that for any non-empty collection it will throw the IllegalArgumentException because elements are compared to themselves. Adding a check for x != y to the condition would solve that but the code is still somewhat slow because it has a time complexity of O(n2).

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

This can be solved to use a set instead of a list. However, a HashSet would depend on how equals() and hashCode() define equality, which doesn't seem to match your requirements. That could be solved by using a wrapper object that implements both methods as needed.

一种更好的方法可能是使用TreeSet. TreeSet使用比较来确定顺序和相等性(如果比较结果为0),因此可以让您像以前一样让Genre类实现Comparable或提供单独的Comparator(例如,如果需要平等的多种不同定义.)

A better approach might be to use a TreeSet though. TreeSet uses comparisons to determine order and equality (if the compare result is 0) and thus would allow you to either let your Genre class implement Comparable as you did or provide a separate Comparator (e.g. if you need multiple different definitions of equality).

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

If you just want to eliminate duplicates, your code could then look like this:

public class GenreManager{
   private SortedSet<Genre> genres;
   ...

   public GenreManager(Collection<Genre> genres){
     this.genres = new TreeSet<>( genres );
   }
}

如果您想知道集合中有哪些重复项,可以这样做:

If you want to know what duplicates are in the collection you could do it like this:

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

这篇关于使用Collections.sort时-不存在变量T的实例,因此Collection符合等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆