如何在Java中对对象数组进行排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18895915/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 12:02:17  来源:igfitidea点击:

How to sort an array of objects in Java?

javaarraysstringsortingobject

提问by Tushar Monirul

My array does not contain any string. But its contains object references. Every object reference returns name, id, author and publisher by toString method.

我的数组不包含任何字符串。但它包含对象引用。每个对象引用都通过 toString 方法返回名称、ID、作者和出版商。

public String toString() {
        return (name + "\n" + id + "\n" + author + "\n" + publisher + "\n");
}

Now I need to sort that array of objects by the name. I know how to sort, but I do not know how to extract the name from the objects and sort them.

现在我需要按名称对该对象数组进行排序。我知道如何排序,但我不知道如何从对象中提取名称并对其进行排序。

采纳答案by A4L

You have two ways to do that, both use the Arraysutility class

您有两种方法可以做到这一点,都使用Arrays实用程序类

  1. Implement a Comparatorand pass your array along with the comparator to the sort methodwhich take it as second parameter.
  2. Implement the Comparableinterface in the class your objects are from and pass your array to the sort methodwhich takes only one parameter.
  1. 实现一个Comparator并将您的数组与比较器一起传递给将它作为第二个参数的sort 方法
  2. 在您的对象所在的类中实现Comparable接口,并将您的数组传递给仅采用一个参数的sort 方法

Example

例子

class Book implements Comparable<Book> {
    public String name, id, author, publisher;
    public Book(String name, String id, String author, String publisher) {
        this.name = name;
        this.id = id;
        this.author = author;
        this.publisher = publisher;
    }
    public String toString() {
        return ("(" + name + ", " + id + ", " + author + ", " + publisher + ")");
    }
    @Override
    public int compareTo(Book o) {
        // usually toString should not be used,
        // instead one of the attributes or more in a comparator chain
        return toString().compareTo(o.toString());
    }
}

@Test
public void sortBooks() {
    Book[] books = {
            new Book("foo", "1", "author1", "pub1"),
            new Book("bar", "2", "author2", "pub2")
    };

    // 1. sort using Comparable
    Arrays.sort(books);
    System.out.println(Arrays.asList(books));

    // 2. sort using comparator: sort by id
    Arrays.sort(books, new Comparator<Book>() {
        @Override
        public int compare(Book o1, Book o2) {
            return o1.id.compareTo(o2.id);
        }
    });
    System.out.println(Arrays.asList(books));
}

Output

输出

[(bar, 2, author2, pub2), (foo, 1, author1, pub1)]
[(foo, 1, author1, pub1), (bar, 2, author2, pub2)]

回答by zbess

You can try something like this:

你可以尝试这样的事情:

List<Book> books = new ArrayList<Book>();

Collections.sort(books, new Comparator<Book>(){

  public int compare(Book o1, Book o2)
  {
     return o1.name.compareTo(o2.name);
  }
});

回答by ROMANIA_engineer

Java 8

爪哇 8



Using lambda expressions

使用lambda 表达式

Arrays.sort(myTypes, (a,b) -> a.name.compareTo(b.name));

Test.java

测试.java

public class Test {

    public static void main(String[] args) {

        MyType[] myTypes = {
                new MyType("John", 2, "author1", "publisher1"),
                new MyType("Marry", 298, "author2", "publisher2"),
                new MyType("David", 3, "author3", "publisher3"),
        };

        System.out.println("--- before");
        System.out.println(Arrays.asList(myTypes));
        Arrays.sort(myTypes, (a, b) -> a.name.compareTo(b.name));
        System.out.println("--- after");
        System.out.println(Arrays.asList(myTypes));

    }

}

MyType.java

我的类型

public class MyType {

    public String name;
    public int id;
    public String author;
    public String publisher;

    public MyType(String name, int id, String author, String publisher) {
        this.name = name;
        this.id = id;
        this.author = author;
        this.publisher = publisher;
    }

    @Override
    public String toString() {
        return "MyType{" +
                "name=" + name + '\'' +
                ", id=" + id +
                ", author='" + author + '\'' +
                ", publisher='" + publisher + '\'' +
                '}' + System.getProperty("line.separator");
    }
}

Output:

输出:

--- before
[MyType{name=John', id=2, author='author1', publisher='publisher1'}
, MyType{name=Marry', id=298, author='author2', publisher='publisher2'}
, MyType{name=David', id=3, author='author3', publisher='publisher3'}
]
--- after
[MyType{name=David', id=3, author='author3', publisher='publisher3'}
, MyType{name=John', id=2, author='author1', publisher='publisher1'}
, MyType{name=Marry', id=298, author='author2', publisher='publisher2'}
]


Using method references

使用方法引用

Arrays.sort(myTypes, MyType::compareThem);

where compareThemhas to be added in MyType.java:

其中,compareThem已经在加入MyType.java

public static int compareThem(MyType a, MyType b) {
    return a.name.compareTo(b.name);
}

回答by Stephen Barner

Sometimes you want to sort an array of objects on an arbitrary value. Since compareTo() always uses the same information about the instance, you might want to use a different technique. One way is to use a standard sorting algorithm. Let's say you have an array of books and you want to sort them on their height, which is stored as an int and accessible through the method getHeight(). Here's how you could sort the books in your array. (If you don't want to change the original array, simply make a copy and sort that.)

有时您想根据任意值对对象数组进行排序。由于 compareTo() 始终使用有关实例的相同信息,因此您可能需要使用不同的技术。一种方法是使用标准排序算法。假设您有一个书籍数组,并且您想根据它们的高度对它们进行排序,该高度存储为一个 int 并且可以通过方法 getHeight() 访问。这是对数组中的书籍进行排序的方法。(如果您不想更改原始数组,只需复制并排序即可。)

`int tallest; // the index of tallest book found thus far
 Book temp; // used in the swap
 for(int a = 0; a < booksArray.length - 1; a++) {
   tallest = a; // reset tallest to current index
   // start inner loop at next index
   for(int b = a + 1; b < booksArray.length; b++)
     // check if the book at this index is taller than the
     // tallest found thus far
     if(booksArray[b].getHeight() > booksArray[tallest].getHeight())
       tallest = b;
   // once inner loop is complete, swap the tallest book found with
   // the one at the current index of the outer loop
   temp = booksArray[a];
   booksArray[a] = booksArray[tallest];
   booksArray[tallest] = temp;
 }`

When this code is done, the array of Book object will be sorted by height in descending order--an interior designer's dream!

这段代码完成后,Book对象的数组会按照高度降序排列——室内设计师的梦想!

回答by Ali

With Java 8, you can use a reference method.

Java 8 中,您可以使用引用方法。

You could add comparemethod to your Bookclass

你可以compare在你的Book类中添加方法

class Book {
     public static int compare(Book a, Book b)
     {
         return a.name.compareTo(b.name);
     }
}

And then you could do this :

然后你可以这样做:

Arrays.sort(books , Book::compare);

Here is the full example:

这是完整的示例:

class Book {
    String name;
    String author;

    public Book(String name, String author) {
        this.name = name;
        this.author = author;
    }

    public static int compareBooks(Book a , Book b)
    {
        return a.name.compareTo(b.name);
    }

    @Override
    public String toString() {
        return "name : " + name + "\t" + "author : " + author;
    }


    public static void main(String[] args) {

        Book[] books = {
                new Book("Book 3" , "Author 1"),
                new Book("Book 2" , "Author 2"),
                new Book("Book 1" , "Author 3"),
                new Book("Book 4" , "Author 4")
        };

        Arrays.sort(books , Book::compareBooks);
        Arrays.asList(books).forEach(System.out::println);

    }
}

回答by Manash Ranjan Dakua

public class Student implements Comparable<Student> {

    private int sid;
    private String sname;

    public Student(int sid, String sname) {
        super();
        this.sid = sid;
        this.sname = sname;
    }

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    @Override
    public String toString() {
        return "Student [sid=" + sid + ", sname=" + sname + "]";
    }

    public int compareTo(Student o) {
        if (this.getSname().compareTo(o.getSname()) > 1) {
            return toString().compareTo(o.getSname());
        } else if (this.getSname().compareTo(o.getSname()) < 1) {
            return toString().compareTo(o.getSname());
        }
        return 0;
    }

}

回答by Manash Ranjan Dakua

import java.util.Collections;

import java.util.List;

import java.util.ArrayList;


public class Test {

public static void main(String[] args) {

   List<Student> str = new ArrayList<Student>();

   str.add(new Student(101, "aaa"));

   str.add(new Student(104, "bbb"));

   str.add(new Student(103, "ccc"));

   str.add(new Student(105, "ddd"));

   str.add(new Student(104, "eee"));

   str.add(new Student(102, "fff"));




   Collections.sort(str);
    for(Student student : str) {

        System.out.println(student);
    }

}
}

回答by Devashish Priyadarshi

You can implement the "Comparable" interface on a class whose objects you want to compare.

您可以在要比较其对象的类上实现“Comparable”接口。

And also implement the "compareTo" method in that.

并在其中实现“compareTo”方法。

Add the instances of the class in an ArrayList

在 ArrayList 中添加类的实例

Then the "java.utils.Collections.sort()" method will do the necessary magic.

然后“java.utils.Collections.sort()”方法将发挥必要的作用。

Here's--->(https://deva-codes.herokuapp.com/CompareOnTwoKeys) a working example where objects are sorted based on two keys first by the id and then by name.

这是 --->( https://deva-codes.herokuapp.com/CompareOnTwoKeys) 一个工作示例,其中对象首先按 id 然后按名称基于两个键进行排序。

回答by shriyog

Update for Java 8 constructs

Java 8 结构的更新

Assuming a Bookclass with a namefield getter, you can use Arrays.sortmethod by passing an additional Comparatorspecified using Java 8 constructs - Comparator default method& method references.

假设一个Book具有name字段 getter的类,您可以Arrays.sort通过传递Comparator使用 Java 8 构造的附加指定来使用方法-比较器默认方法方法引用

Arrays.sort(bookArray, Comparator.comparing(Book::getName));

Also, it's possible to compare on multiple fields using thenComparingmethods.

此外,可以使用thenComparing方法对多个字段进行比较。

Arrays.sort(bookArray, Comparator.comparing(Book::getName)
      .thenComparing(Book::getAuthor))
      .thenComparingInt(Book::getId));

回答by Mehmet Onar

Arrays.sort(yourList,new Comparator<YourObject>() {

    @Override
    public int compare(YourObjecto1, YourObjecto2) {
        return compare(o1.getYourColumn(), o2.getYourColumn());
    }
});