简体   繁体   中英

Sort an Arraylist by two fields (Java)

I have an arraylist of highscores for a card game I am making. There needs to be a finite limit on the number of scores this arraylist can store, which the user of the system may define (let's say 10 for now). The fields in the objects in the arraylist are the player's name (string), their score (int) and a (almost) unique ID for the player (Long, System.currentTimeMillis()). The arraylist should be sorted by the score, where the lowest score is the best. However, if all players in the arraylist have the same score and a new player is added with that score, I would like the players with the most recent scores (the ones for whom the ID is highest) to be stored before the older ones, so the older ones are discarded.

Essentially I need a way to sort an ArrayList by two fields- score first, low to high, then if the scores match sort those by the ID. Removing excess elements I already have mostly covered, although if there is a way to integrate that I would be interested to hear it.

EDIT: I'm trying to sort an Arraylist of objects with those attributes, not a single arraylist with them just thrown in. My bad.

If you use Java 8, there is a neat way of nesting comparators with method references:

List<Player> players = // ...

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

More information can be found in the Comparator JavaDoc .

Don't use an ArrayList to hold your data.

Create a custom object with Id, name, score ... properties. Then you create a custom Comparator ,

Here is an example of a simple custom Object and a custom Comparator. You would modify the Comparator to implement the logic that you just described.

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

You can use 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;
   }

  }

Sorting my list

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

        }
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM