简体   繁体   中英

Sorting an array list of custom java classes based on variable

I have a custom Java class which contains two variables: username and score .

I am looking to create an ArrayList with multiple of these inside. I then want to sort them in order of lowest to highest, based on the value of their score

Highscore.class

public class Highscore implements ConfigurationSerializable {

    String username;
    int score;

    public Highscore(String username, int score) {
        this.username = username;
        this.score = score;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

    @Override
    public Map<String, Object> serialize() {
        Map<String, Object> mappedObject = new LinkedHashMap<String, Object>();
        mappedObject.put("username", username);
        mappedObject.put("score", score);
        return mappedObject;
    }

    public static Highscore deserialize(Map<String, Object> mappedObject) {
        return new Highscore((String) mappedObject.get("username"),
                (int) mappedObject.get("score"));
    }
}

For example, below shows the ArrayList containing multiple Highscore 's. I want to look only at the score based on low to high, and then sort the Highscore 's into another ArrayList.

ArrayList<Highscore> highscores = new ArrayList<>();
highscores.add(new Highscore("user1", 10));
highscores.add(new Highscore("user2", 0));
highscores.add(new Highscore("user3", -15));
highscores.add(new Highscore("user4", 30));
highscores.add(new Highscore("user5", 5));

// Now, sort the highscores based on their 'score'

Thanks in advance.

Are you really restricted to use only List ?

IMO SortedSet is better suited for your goal. You can use TreeSet Notice that TreeSet elements are ordered using their natural ordering, or by a Comparator provided at set creation time. Also, it provides guaranteed log(n) time cost for the basic operations (add, remove and contains), so it's computationally pretty efficient.

For example, you can do the following:

SortedSet<Highscore> highscores =
  new TreeSet<>(Comparator.comparingInt(highscore -> highscore.score));
highscores.add(new Highscore("user1", 10));
highscores.add(new Highscore("user2", 0));
highscores.add(new Highscore("user3", -15));
highscores.add(new Highscore("user4", 30));
highscores.add(new Highscore("user5", 5));

Now highscores contains all your objects sorted ascending by score .

Also, if you need to get List from highscores , then simply:

List<Highscore> highscoreList = new ArrayList<>(highscores);

The advantage of this approach: is better flexibility and efficiency, because after SortedSet is formed any queries will cost you O(log n) or O(n) time. And if you use List you will always be forced to perform sort, that will take O(n log n) .

You can use a comparator, or let you class implement the comparable interface. Take a look at: Java : Comparable vs Comparator

public class CustomComparator implements Comparator<Highscore> 
{
   public int compare(HighScore h1, HighScore h2) {
      return h1.getScore().compareTo(h2.getScore());
   }
}

Probably you need something like this

ArrayList<Highscore> sortedHighscores = highscores.stream()
            .sorted(Comparator.comparingInt(Highscore::getScore))
            .collect(Collectors.toList());

or

ArrayList<Highscore> sortedHighscores = highscores.stream()
                .sorted(Comparator.comparingInt(Highscore::getScore).reversed())
                .collect(Collectors.toList());

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