【问题标题】:Sort an Arraylist by two fields (Java)按两个字段对 Arraylist 进行排序(Java)
【发布时间】:2015-05-01 19:11:55
【问题描述】:

我有一个我正在制作的纸牌游戏的高分数组列表。这个arraylist可以存储的分数需要有一个有限的限制,系统的用户可以定义(假设现在是10)。数组列表中对象中的字段是玩家的姓名(字符串)、他们的分数(int)和玩家的(几乎)唯一的 ID(Long,System.currentTimeMillis())。 arraylist 应该按分数排序,其中分数最低的是最好的。但是,如果 arraylist 中的所有玩家都具有相同的分数并且添加了具有该分数的新玩家,我希望将具有最新分数的玩家(ID 最高的玩家)存储在较旧的玩家之前,所以旧的被丢弃了。

基本上我需要一种方法来按两个字段对 ArrayList 进行排序——首先是得分,从低到高,然后如果得分匹配,则按 ID 对它们进行排序。删除我已经主要介绍过的多余元素,但如果有一种整合方式,我会很感兴趣。

编辑:我正在尝试对具有这些属性的对象的 Arraylist 进行排序,而不是对刚刚放入它们的单个 Arraylist 进行排序。我的错。

【问题讨论】:

  • 请贴出你目前写的代码。
  • 你卡在哪里了?
  • 你能不能只创建一个类来存储你的数据,实现可比较的docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html,然后运行标准的 Collections.sort 函数?
  • object ordering 上的 Java 教程可能会有所帮助。
  • @mattias 我不知道如何对两个字段进行排序。我只知道一种排序方法。

标签: java arraylist


【解决方案1】:

如果您使用 Java 8,有一种巧妙的方法可以将比较器与方法引用嵌套:

List<Player> players = // ...

players.sort(Comparator
    .comparing(Player::getScore)
    .thenComparing(Player::getId));

更多信息可以在ComparatorJavaDoc找到。

【讨论】:

  • Java 突然变得如此性感,你不喜欢吗? :)
  • @matsev 我收到错误消息:Comparator 类型中的方法 compare(Function super T,? extends U>) 不适用于参数 (PlayerScore::getpilesRemaining), PlayerScore 类型未定义此处适用的 getpilesRemaining(Object),PlayerScore 类型未定义此处适用的 getUniqueID(Object, Object)。不知道怎么回事
【解决方案2】:

不要使用 ArrayList 来保存数据。

创建一个具有 Id、name、score ... 属性的自定义对象。然后你创建一个自定义的Comparator

这是一个简单的自定义对象和自定义比较器的示例。您将修改 Comparator 以实现您刚刚描述的逻辑。

/*
**  Use the Collections API to sort a List for you.
**
**  When your class has a "natural" sort order you can implement
**  the Comparable interface.
**
**  You can use an alternate sort order when you implement
**  a Comparator for your class.
*/
import java.util.*;

public class Person implements Comparable<Person>
{
    String name;
    int age;

    public Person(String name, int age)
    {
        this.name = name;
        this.age = age;
    }

    public String getName()
    {
        return name;
    }

    public int getAge()
    {
        return age;
    }

    public String toString()
    {
        return name + " : " + age;
    }

    /*
    **  Implement the natural order for this class
    */
    public int compareTo(Person p)
    {
        return getName().compareTo(p.getName());
    }

    static class AgeComparator implements Comparator<Person>
    {
        public int compare(Person p1, Person p2)
        {
            return p1.getAge() - p2.getAge();
        }
    }

    public static void main(String[] args)
    {
        List<Person> people = new ArrayList<Person>();
        people.add( new Person("Homer", 38) );
        people.add( new Person("Marge", 35) );
        people.add( new Person("Bart", 15) );
        people.add( new Person("Lisa", 13) );

        // Sort by natural order

        Collections.sort(people);
        System.out.println("Sort by Natural order");
        System.out.println("\t" + people);

        // Sort by reverse natural order

        Collections.sort(people, Collections.reverseOrder());
        System.out.println("Sort by reverse natural order");
        System.out.println("\t" + people);

        //  Use a Comparator to sort by age

        Collections.sort(people, new Person.AgeComparator());
        System.out.println("Sort using Age Comparator");
        System.out.println("\t" + people);

        //  Use a Comparator to sort by descending age

        Collections.sort(people, Collections.reverseOrder(new Person.AgeComparator()));
        System.out.println("Sort using Reverse Age Comparator");
        System.out.println("\t" + people);
    }
}

【讨论】:

  • 在这种情况下 ArrayList 有什么问题?您可以使用 Comparator 对 ArrayList 进行排序。
  • @eckes,它 ArrayList 包含相同的数据,这很好,但您不应该使用 ArrayList 来保存 OP 描述的不同字段。您创建一个自定义对象,以便您可以为每个字段设置 getter/setter。
  • 啊,我的错。它是我要排序的自定义对象的 Arraylist。我将编辑问题。
  • @camickr 是的,“不要为每个字段使用单独条目的列表”。同意。
【解决方案3】:

您可以使用 Collections.sort()

 Class Student{

   String fname="";
   String lname="";
   int age =0;
   int score=0;

   public Student(String fname,String lname,int age, int score)
   {
       this.fname=fname;
       this.lname=lname;
       this.age=age;
       this.score=score;
   }

  }

排序我的列表

    ArrayList<Student> list = new ArrayList<Student>();
     /*add elements*/
    Collections.sort(list, new Comparator<Student>() 
    {
        @Override
        public int compare(Student x, Student y)
        {
            if(x.score == y.score)
            {
                 return (y.age-x.age);
            }
            else 
                return (y.score-x.score);

        }
    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-18
    • 2019-08-02
    • 1970-01-01
    • 2011-08-12
    • 2011-07-09
    相关资源
    最近更新 更多