41

Lets say you have an Arraylist of HockeyPlayer objects.

How could you sort that if they all have a variable int goalsScored. How could you sort them by goalsScored?

Arpit Aggarwal
29.4k16 gold badges96 silver badges110 bronze badges
asked Mar 29, 2010 at 0:04
1

7 Answers 7

95

You can use Collections.sort with a custom Comparator<HockeyPlayer>.

 class HockeyPlayer {
 public final int goalsScored;
 // ...
 };
 List<HockeyPlayer> players = // ...
 Collections.sort(players, new Comparator<HockeyPlayer>() {
 @Override public int compare(HockeyPlayer p1, HockeyPlayer p2) {
 return p1.goalsScored - p2.goalsScored; // Ascending
 }
 });

The comparision part can also be written this way :

players.sort(Comparator.comparingInt(HockeyPLayer::goalsScored));

Alternatively, you can make HockeyPlayer implementsComparable<HockeyPlayer>. This defines the natural ordering for all HockeyPlayer objects. Using a Comparator is more flexible in that different implementations can order by name, age, etc.

See also


For completeness, I should caution that the return o1.f - o2.f comparison-by-subtraction shortcut must be used with extreme caution due to possible overflows (read: Effective Java 2nd Edition: Item 12: Consider implementing Comparable). Presumably hockey isn't a sport where a player can score goals in the amount that would cause problems =)

See also

answered Mar 29, 2010 at 5:49

5 Comments

Do self-goals count as negatives? Because if goalsScored is strictly positive, then the subtraction trick is fine.
Own goals count as a goal for the last person on the other team who touched the puck, so goalsScored would never be negative. Even if it was negative though I think the subtraction trick still works.
return p1.goalsScored - p2.goalsScored; can be replaced by return Integer.compare(p1.goalsScored,p2.goalsScored); to avoid integer overflow if goalsScored can have negative value. Also since Java 8 this code can be replaced by Collections.sort(players, Comparator.comparingInt(h -> h.goalsScored));.
@Pshemo great solution, fixed a lookalike problem with your solution.
@Pshemo thanks this was useful when my property to compare is a long - I could use return Long.compare(p1.getLongValue(), p2.getLongValue());
7

As @user6158055 suggets, it's one liner with Java 8, as follows:

Collections.sort(
 hockeyPlayerList,
 (player1, player2) -> player1.getGoalsScored()
 - player2.getGoalsScored());

Complete example to depict the same:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
 public static void main(String[] args) {
 List<HockeyPlayer> hockeyPlayerList = new ArrayList<>();
 hockeyPlayerList.add(new HockeyPlayer("A", 3));
 hockeyPlayerList.add(new HockeyPlayer("D", 10));
 hockeyPlayerList.add(new HockeyPlayer("B", 2));
 System.out.println("Before Sort based on goalsScored\n");
 hockeyPlayerList.forEach(System.out::println);
 System.out.println("\nAfter Sort based on goalsScored\n");
 Collections.sort(
 hockeyPlayerList,
 (player1, player2) -> player1.getGoalsScored()
 - player2.getGoalsScored());
 hockeyPlayerList.forEach(System.out::println);
 }
 static class HockeyPlayer {
 private String name;
 private int goalsScored;
 public HockeyPlayer(final String name, final int goalsScored) {
 this.name = name;
 this.goalsScored = goalsScored;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public int getGoalsScored() {
 return goalsScored;
 }
 public void setGoalsScored(int goalsScored) {
 this.goalsScored = goalsScored;
 }
 @Override
 public String toString() {
 return "HockeyPlayer [name=" + name + ", goalsScored="
 + goalsScored + "]";
 }
 }
}

Output:

Before Sort based on goalsScored
HockeyPlayer [name=A, goalsScored=3]
HockeyPlayer [name=D, goalsScored=10]
HockeyPlayer [name=B, goalsScored=2]
After Sort based on goalsScored
HockeyPlayer [name=B, goalsScored=2]
HockeyPlayer [name=A, goalsScored=3]
HockeyPlayer [name=D, goalsScored=10]
answered Sep 7, 2016 at 5:47

Comments

5

Just one line with Java 8 :

Collections.sort(players, (p1, p2) -> p1.getGoalsScored() - p2.getGoalsScored());
answered May 8, 2016 at 13:07

2 Comments

how to do the same for the property with string data type
btw i found out a way to sort for string Collections.sort( people, (player1, player2) -> player1.getLastName().compareTo(player2.getLastName()));
3

Write a custom Comparator to do the job.

answered Mar 29, 2010 at 0:06

Comments

2

Use a generic Comparator like the Bean Comparator.

answered Mar 29, 2010 at 0:08

Comments

1

With Java 8 this is simple

Collections.sort(playList, Comparator.comparingInt(HockeyPLayer::goalsScored))
answered Nov 9, 2018 at 0:14

Comments

0

Java has a set of sort() methods for this sort of thing. See Collections.sort (and Comparable) for details.

answered Mar 29, 2010 at 0:10

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.