简体   繁体   English

如何对通用对象列表进行排序

[英]How to sort a List of generic objects

I'm struggling with sorting an ArrayList of a generic objects.我正在努力对通用对象的ArrayList进行排序。

I've tried to do it with Comparable interface, but it doesn't work, I've also tried with sort method of collections, but I'm still at the same point.我试过用Comparable接口来做,但它不起作用,我也尝试过使用集合的排序方法,但我仍然在同一点上。

public class League<T extends Player> implements LeagueComparator<T> {
    private String name;

    private ArrayList<Team<T>> teams = new ArrayList<>();
    public void ranking(){
        for (Team<T> team : teams){
            System.out.println(team.getName() + team.ranking());
            int ranking = team.ranking();

            Collections.sort(teams, new Comparator<Team<T>>() {
                @Override
                public int compare(Team<T> o1, Team<T> o2) {
                    return 

In this method, I want to take a ranking integer from Team class and sort it, and then return the sorted values在这种方法中,我想从 Team 类中获取一个排名整数并对其进行排序,然后返回排序后的值

public class Team<T extends Player> {
    private int size = 0;
    private String name;
    private int games;
    private int win;
    private int lose;
    private int draw;

    private ArrayList<T> members = new ArrayList<>();

    public int ranking(){
        return (win * 2) + draw;
    }

This is Team class EDIT这是团队班编辑

    System.out.println(team.ranking() + " " + team.getName());         
    Collections.sort(teams, Comparator.comparingInt(team::rankings));  
    System.out.println(team.ranking() + " " + team.getName());        

Now it throws现在它抛出

Exception in thread "main"
java.util.ConcurrentModificationException

Simply returns the difference in ranking of o1 and o2.简单地返回 o1 和 o2 的排名差异。

Collections.sort(teams, new Comparator<Team<T>>() {
  @Override
  public int compare(Team<T> o1, Team<T> o2) {
    return o1.ranking() - o2.randking();
  }
});

Comparable可比

I tried with Comparable interface but it doesn't work我尝试使用Comparable接口,但它不起作用

If there's only one way to compare teams that make sense from the perspective of your application - by their ranking , then Team objects have a natural ordering and hence class Team should implement Comparable .如果只有一种方法可以比较从应用程序的角度有意义的团队- 通过他们的排名,那么Team对象具有自然排序,因此类Team应该实现Comparable

A quote from the documentation : 文档中的引用:

This interface imposes a total ordering on the objects of each class that implements it.该接口对实现它的每个类的对象进行了总排序。 This ordering is referred to as the class's natural ordering , and the class's compareTo method is referred to as its natural comparison method .这种排序称为类的自然排序,类的compareTo方法称为其自然比较方法

That's how it might be done:这就是它可以做到的方式:

public static class Team<T extends Player> implements Comparable<Team<T>> {
    public static final Comparator<Team<? extends Player>> BY_TEAM_RANKING =
        Comparator.comparingInt(Team::ranking);
    
    // fields, getters, etc.

    public int ranking() {
        return (win * 2) + draw;
    }

    @Override
    public int compareTo(Team<T> other) {
        return BY_TEAM_RANKING.compare(this, other);
    }
}

For the sake of conciseness, method compareTo in the code shown above internally uses Comparator defined as a static field ( similar approach you can find in the book "Effective Java" by Joshua Bloch, have a look at it for more information on implementing Comparable interface ).为了简洁起见,上面显示的代码中的方法compareTo在内部使用Comparator定义为static字段(您可以在 Joshua Bloch 的“Effective Java”一书中找到类似的方法,查看它以获取有关实现Comparable接口的更多信息)。

To sort the list of teams , use method sort() directly on the list (which is a more fluent alternative of Collection.sort() introduced with Java 8).要对 team列表进行排序,请直接在列表上使用方法sort() (这是 Java 8 引入的Collection.sort()的更流畅的替代方法)。

public class League<T extends Player> {
    
    private String name;
    private List<Team<T>> teams = new ArrayList<>();
    
    public void ranking() {
        teams.sort(null); // teams are comparable, hence no need to provide a comparator and null is passed as an argument
    }
}

Comparators比较器

In case if there are multiple ways how teams need to be sorted in different scenarios, then Team class should not implement Comparable , don't go with way.如果在不同的场景中需要对团队进行多种排序,那么Team类不应该实现Comparable ,不要随心所欲。

You can define comparators for different use-cases as public static fields in the Team class, like below:您可以将不同用例的比较器定义为Team类中的public static字段,如下所示:

public static class Team<T extends Player> {
    
    public static final Comparator<Team<? extends Player>> BY_TEAM_RANKING =
        Comparator.comparingInt(Team::ranking);
    
    public static final Comparator<Team<? extends Player>> BY_TEAM_NAME =
        Comparator.comparing(Team::getName);
    
    // the rest code
}

And then apply them depending on a particular case:然后根据特定情况应用它们:

public void ranking() {
    teams.sort(Team.BY_TEAM_RANKING);
}

Sidenote: write your code against interfaces, not implementations like ArrayList .旁注:针对接口编写代码,而不是ArrayList这样的实现。 See What does it mean to "program to an interface"?请参阅“编程到接口”是什么意思?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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