【问题标题】:How to sort an array of objects in Java?如何在 Java 中对对象数组进行排序?
【发布时间】:2021-04-15 00:21:24
【问题描述】:

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

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

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

【问题讨论】:

  • 实现一个Comparator 并将其用于排序。
  • Comparator中拆分字符串并使用第一个元素作为名称。

标签: java arrays string sorting object


【解决方案1】:

你可以试试这样的:

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

【讨论】:

    【解决方案2】:

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

    1. 实现Comparator 并将您的数组与比较器一起传递给sort method,后者将其作为第二个参数。
    2. 在您的对象所在的类中实现Comparable 接口,并将您的数组传递给只接受一个参数的sort method

    示例

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

    输出

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

    【讨论】:

      【解决方案3】:

      Java 8


      使用lambda expressions

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

      Test.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");
          }
      }
      

      输出:

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

      使用method references

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

      compareThem 必须在 MyType.java 中添加:

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

      【讨论】:

      • 如果你想在 Android Studio 中使用 lambda 表达式,你应该看看这个页面:developer.android.com/studio/write/java8-support.html
      • 上述情况,如果是id,而不是name,怎么办?
      • 我尝试将name替换为id,但错误是“int无法解除引用,”所以我将int转换为字符串。现在没有错误,但它没有排序?跨度>
      【解决方案4】:

      Java 8 结构更新

      假设Book 类具有name 字段getter,您可以通过传递使用Java 8 构造指定的额外Comparator - Comparator default methodmethod references 来使用Arrays.sort 方法。

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

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

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

      【讨论】:

        【解决方案5】:
        [Employee(name=John, age=25, salary=3000.0, mobile=9922001), 
         Employee(name=Ace, age=22, salary=2000.0, mobile=5924001), 
         Employee(name=Keith, age=35, salary=4000.0, mobile=3924401)]
        
        public void whenComparing_thenSortedByName() {
            Comparator<Employee> employeeNameComparator
                    = Comparator.comparing(Employee::getName);
            Arrays.sort(employees, employeeNameComparator);
            assertTrue(Arrays.equals(employees, sortedEmployeesByName));
        }
        

        结果

        [Employee(name=Ace, age=22, salary=2000.0, mobile=5924001), 
         Employee(name=John, age=25, salary=3000.0, mobile=9922001), 
         Employee(name=Keith, age=35, salary=4000.0, mobile=3924401)]
        

        【讨论】:

          【解决方案6】:

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

          您可以将 compare 方法添加到您的 Book 类中

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

          然后你可以这样做:

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

          这里是完整的例子:

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

          【讨论】:

          【解决方案7】:
          Arrays.sort(yourList,new Comparator<YourObject>() {
          
              @Override
              public int compare(YourObjecto1, YourObjecto2) {
                  return compare(o1.getYourColumn(), o2.getYourColumn());
              }
          });
          

          【讨论】:

          • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。Read this
          【解决方案8】:

          有时您想根据任意值对对象数组进行排序。由于 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;
           }`
          

          完成此代码后,Book 对象的数组将按高度降序排序——室内设计师的梦想!

          【讨论】:

            【解决方案9】:

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

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

            在 ArrayList 中添加类的实例

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

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

            【讨论】:

              【解决方案10】:
              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;
                  }
              
              }
              

              【讨论】:

              • 在下面的应用程序的测试类中添加排序检查
              【解决方案11】:
              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);
                      }
                  }
              }
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-03-05
                • 1970-01-01
                • 2016-10-30
                • 1970-01-01
                • 2012-04-14
                • 2019-11-02
                • 2010-12-04
                相关资源
                最近更新 更多