【问题标题】:How to sort an arraylist of objects by a property?如何按属性对对象数组列表进行排序?
【发布时间】:2011-02-01 20:52:20
【问题描述】:

假设您有一个 ArraylistHockeyPlayer 对象。

如果它们都有一个变量int targetsScored,你怎么能对它进行排序。您如何按目标得分对它们进行排序?

【问题讨论】:

标签: java sorting collections


【解决方案1】:

编写自定义Comparator 来完成这项工作。

【讨论】:

    【解决方案2】:

    使用像Bean Comparator 这样的通用比较器。

    【讨论】:

      【解决方案3】:

      Java 有一组 sort() 方法来处理这类事情。有关详细信息,请参阅 Collections.sort(和 Comparable)。

      【讨论】:

        【解决方案4】:

        您可以将Collections.sort 与自定义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
                }
        
            });
        

        比较部分也可以这样写:

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

        或者,您可以创建HockeyPlayer implementsComparable&lt;HockeyPlayer&gt;。这定义了所有HockeyPlayer 对象的 自然顺序。使用Comparator 更灵活,因为不同的实现可以按名称、年龄等排序。

        另见


        为了完整起见,我应该注意return o1.f - o2.f 减法比较快捷方式必须非常小心地使用,因为它可能会溢出(阅读:Effective Java 2nd Edition:第 12 项:考虑实现Comparable)。据推测,曲棍球不是一项运动员可以进球的运动会导致问题的数量=)

        另见

        【讨论】:

        • 自我目标算不算负面?因为如果goalsScored 是严格正数,那么减法就可以了。
        • 乌龙球是对方球队最后一个触球者的进球,所以goalsScored 永远不会是负数。即使它是负面的,尽管我认为减法技巧仍然有效。
        • return p1.goalsScored - p2.goalsScored; 可以替换为return Integer.compare(p1.goalsScored,p2.goalsScored);,以避免在goalsScored 可以为负值时整数溢出。此外,从 Java 8 开始,此代码可以替换为 Collections.sort(players, Comparator.comparingInt(h -&gt; h.goalsScored));
        • @Pshemo 很棒的解决方案,解决了与您的解决方案相似的问题。
        • @Pshemo 谢谢,当我要比较的属性很长时,这很有用 - 我可以使用 return Long.compare(p1.getLongValue(), p2.getLongValue());
        【解决方案5】:

        Java 8 只需一行:

        Collections.sort(players, (p1, p2) -> p1.getGoalsScored() - p2.getGoalsScored());
        

        【讨论】:

        • 如何对字符串数据类型的属性做同样的事情
        • 顺便说一句,我找到了一种对字符串进行排序的方法Collections.sort( people, (player1, player2) -&gt; player1.getLastName().compareTo(player2.getLastName()));
        【解决方案6】:

        正如@user6158055 建议的那样,它与Java 8 是一列,如下:

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

        描述相同的完整示例:

        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 + "]";
                }
        
            }
        }
        

        输出

        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]
        

        【讨论】:

          【解决方案7】:

          使用 Java 8 这很简单

          Collections.sort(playList, Comparator.comparingInt(HockeyPLayer::goalsScored))
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-10-21
            • 1970-01-01
            • 1970-01-01
            • 2011-09-06
            • 2011-08-13
            相关资源
            最近更新 更多