Eclipse不接受Collections sort的问题

4
    import java.io.BufferedReader;
    import java.util.Collections;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.Date;
    import java.util.List;
    import com.javaranch.common.TextFileIn;

    public class SortNames 
    {
        public static class CelebrityNamesFile
        {
            public String firstName;
            public String lastName;

            public static class CompareLastName implements Comparator< CelebrityNamesFile >
            {
                @Override
                public int compare( CelebrityNamesFile o1,  CelebrityNamesFile o2 )
                {
                    return o2.lastName.compareTo( o1.lastName );
                }
            }

        public static void main( String[ ] args ) throws IOException
        {

            ArrayList< CelebrityNamesFile > myCelebrityList;
            myCelebrityList = new ArrayList< CelebrityNamesFile >();

            TextFileIn celebrityNamesFile = new TextFileIn( "celebrityNamesFile.txt" );
            boolean doneReadingCelebrityNames = false;
            while ( ! doneReadingCelebrityNames )
            {
                 String oneName = celebrityNamesFile.readLine();
                 if ( oneName == null )
                 {
                     doneReadingCelebrityNames = true;
                 }

$ Eclipse不喜欢下面的add语句,即:在ArrayList(SortNames.CelebrityNamesFile)中的add方法不适用于参数(String)

                 else
                 {
                     myCelebrityList.add( oneName );
                 }
            }
            celebrityNamesFile.close();

$然后它不喜欢我的排序语句,即: 边界不匹配:类型Collections的通用方法sort(List T)对于参数(ArrayList(SortNames.CelebrityNamesFile))不适用。 推断类型SortNames.CelebrityNamesFile不是有界参数(T extends Comparable(? super T))的有效替代。

            Collections.sort( myCelebrityList );
            System.out.println( myCelebrityList );

            Collections.sort( myCelebrityList, new CelebrityNamesFile.CompareLastName() );
            System.out.println( myCelebrityList );
}
}

我做错了什么?我已经看过这里的很多帖子,已经阅读了有关比较器的Java文档,已经阅读了有关比较器的Java教程。Head First Java、Ivor Horton's Beginning Java 7。仍然一筹莫展。

该程序的目的是从txt文件中读取姓名,将其添加到ArrayList中,按自然顺序打印ArrayList,按姓氏排序ArrayList,再次打印列表。


2
不要写打断代码的散文评论,而应该使用一个可以复制粘贴到IDE中的正确代码块,并用注释指出重要的行。此外,删除import语句,它们只会使代码变得模糊不清。如果需要更长的散文,请参考之前指出的行。 - millimoose
5个回答

12

针对第一个问题,问题相当简单。 oneName是一个String类型的变量,而myCelebrityList则是一个CelebrityNamesFile类型的集合。这意味着您只能向该集合中添加CelebrityNamesFile类型的对象。

至于第二个问题,您遇到的问题是CelebrityNamesFile类没有实现Comparable接口。进行排序需要为列表元素类型实现排序,例如通过为该类实现Comparable或为sort提供Comparator实现。


1
+1 很好的回答...对于新手来说 :) 欢迎来到SO!顺便说一下,它应该实现Comparable<CelebrityNamesFile> - 自1.5版本开始,Comparable是有类型的。 - Bohemian
是的,那是一种方法,但请检查 OP 是否已经实现了 Comparator。 - Luiggi Mendoza
我确实注意到了,但我觉得仅仅告诉别人使用函数的显式比较器版本并不能解释错误消息 :) - alyu

2

针对第一个问题,您正在尝试将一个String添加到一个List<CelebrityNamesFile>实例中。您应该使用该字符串创建一个CelebrityNamesFile实例,并将此实例添加到您的列表中:

CelebrityNamesFile celebrityNamesFile = new CelebrityNamesFile();
celebrityNamesFile.lastName = oneName;
myCelebrityList.add( celebrityNamesFile );

对于第二个问题,请尝试以下操作:

Collections.sort(myCelebrityList, new CompareLastName());

如@alyu所指出,CelebrityNamesFile类需要实现Comparable接口才能与您发布的代码一起使用,但您还可以添加一个Comparator<CelebrityNamesFile>实例(并且您已经有了实现它的CompareLastName类)。
更多信息:

1

CompareLastName 类实现的 Comparator 可以放在 SortNames 类之外,或者至少放在 CelebrityNamesFile 类之外。我也遇到了同样的问题,直到我将实现 Comparator 的类放在我的对象类之外。之后,程序完美地运行了。以下是我的代码示例及其注释,如果有帮助的话。

// Comparator interface for my Word Class.
public interface Comparator<Word>
{ 
    int compare(Word first, Word second); 
}

// Word Class, which is my object.
public class Word
{
    private String word;
    public Word(String input)  { word = input; }
    public String get()  { return word; }
    public int wordSize()  { return word.length(); }
}

// Comparator implementation is separate from my Word Class.
public class WordComparator implements Comparator<Word>
{
    public int compare(Word first, Word second)
    {
        if (first.wordSize() < second.wordSize())  { return -1; }
        else if (first.wordSize() > second.wordSize())  { return 1; }
        else  { return first.get().compareTo(second.get()); }
    }
}

// Now run the program to ensure the Word Class objects and the WordComparator
// Class are implemented correctly.
public class WordComparatorDemo
{
    public static void main(String[] args) throws FileNotFoundException
    {
        ArrayList<Word> list = new ArrayList<Word>();
        JFileChooser find = new JFileChooser();
        Scanner read = null;
        if(find.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
        {
            File selectedFile = find.getSelectedFile();
            read = new Scanner(selectedFile);
            try
            {
                list = inputData(read);
                // Here's the sort implementing the WordComparator.
                Collections.sort(list, new WordComparator());
            }
            finally  { read.close(); }
        }
    }
    public static ArrayList<Word> inputData(Scanner in)
    {
        ArrayList<Word> list = new ArrayList<Word>();
        in.useDelimiter("[^A-Za-z]+");
        while(in.hasNext())
        {
            String word = in.next();
            Word temp = new Word(word);
            list.add(temp);
        }
        return list;
    }
}

注意:我的回答是在原始帖子发布一年后的,但希望它能帮助任何访问这个网站寻求帮助的人。

1
  1. 您正在尝试将一个String(对象oneName)添加到CelebrityNamesFile列表中。您需要以某种方式从此String创建一个CelebrityNamesFile
  2. Collections.sort()仅适用于实现了Comparable接口的对象,如果您没有显式地传递比较器,则会出现问题。请尝试使用以下代码:

    Collections.sort(myCelebrityList, new CelebrityNamesFile.CompareLastName());


1
集合myCelebrityListCelebrityNamesFile类型的,这意味着它只能接受该类的实例。您需要创建一个CelebrityNamesFile实例并将其添加到集合中。由于您的类CelebrityNamesFile没有实现Comparator接口,因此Collections不会接受您的集合。您需要将比较器实例作为第二个参数传递给Collections.sort()函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接