【问题标题】:Produce sorted arraylist from unsorted arraylist in 1 interation?在 1 次交互中从未排序的数组列表生成排序的数组列表?
【发布时间】:2012-11-27 22:20:08
【问题描述】:

假设我有 arraylist A 并比较 A 的 2 个对象,我做 a.getDistanceFromPlayer() < b.getDistanceFromPlayer()

我现在想要列出B,它将包含A 的所有对象,但排序在第一个对象最接近玩家的位置,最后一个对象最远。

最快的方法是什么?

谢谢

【问题讨论】:

  • closes to player - 哪个玩家?
  • 距离已经计算好了,比较只是比较float A和float B

标签: java


【解决方案1】:

让 A 实现 Comparable,然后像这样定义方法 compareTo(Object other):

public int compareTo(Object other) {
  if( this.getDistanceFromPlayer() < other.getDistanceFromPlayer() ) {
      return -1;
  } else if( this.getDistanceFromPlayer() > other.getDistanceFromPlayer())  {
      return 1;
  }
  return 0;
}

现在您可以在对象列表中调用 Collections.sort()

【讨论】:

    【解决方案2】:

    将 Collections.sort 与自定义比较器一起使用。

    eg.
    public class DistanceComparator implements Comparator<Integer>{
    
        @Override
        public int compare(YourObject o1, YourObject o2) {
            if (o1.getDistanceFromPlayer() > o2.getDistanceFromPlayer())
            {
               return 1;
            } 
            else if (o1.getDistanceFromPlayer() < o2.getDistanceFromPlayer())
            {
               return -1;
            }
            return 0;
        }
    }
    

    然后在你的程序中,调用

    Collections.sort(YourArrayInstance, new DistanceComparator())
    

    【讨论】:

      【解决方案3】:

      你应该让你的类实现Comparable

      然后您可以使用Collections.sort() 对您的列表进行排序。

      如果您想要一个排序列表AND一个未排序列表,您必须制作一个副本。


      另一种选择是创建Comparator

      如果您阅读 documentation for Collections,您会发现它有两个 sort 方法。

      排序基于对象的compareTo 方法(即它们的“自然顺序”)。

      另一个基于作为第二个参数传递的 Comparator 进行排序。


      这是另一个问题的链接,提供了 Comparable 的示例实现:

      【讨论】:

      • 我如何实现可比性?
      • 这是一个实现起来非常简单的接口。它只有一个方法,compareTo,它将一个对象与另一个相同类型的实例进行比较。它根据比较返回一个 int。如果您从提供的链接阅读文档,您将了解更多信息。稍后我会发布一个类似问题的链接...
      • 但是,如果您需要根据不同的标准对对象进行排序,使用比较器会更好。
      • @PatriciaShanahan - 同意。如果这是对对象进行排序的默认方式(即对象的自然顺序),则实现Comparable 会更好。如果对象有不同的排序方式,使用 Comparator 会更好。我编辑了我的答案以包含两个选项。
      【解决方案4】:

      使用Custom Comparator

      B = Collections.sort(A, new CustomComparator());
      
      public class CustomComparator implements Comparator<ClassA> {
      
          @Override
          public int compare(final ClassA a, final ClassA b) {
               //Make sure you check that neither a nor b are null..
               //..
               if (a.getDistanceFromPlayer() < b.getDistanceFromPlayer()) {
                   return 1;
               } else if (a.getDistanceFromPlayer() > b.getDistanceFromPlayer()) {
                   return -1;
               }
               return 0;
      
         }
      }
      

      【讨论】:

        【解决方案5】:

        您可以使用自定义Comparatorsort 您的ArrayList,如下所示:

        import java.util.ArrayList;
        import java.util.Collections;
        import java.util.Comparator;
        
        class Main {
            public static class Player {
                private final float distance;
        
                public Player (final float position) {
                    this.distance = position;           
                }
        
                public float getDistanceFrom () {
                    return distance;
                }
        
                @Override
                public String toString() {
                    return "Player [distance=" + distance + "]";
                }
            }
        
            public static void main(String[] args) throws Exception {
                final ArrayList<Player> players = new ArrayList<Player> ();
        
                players.add (new Player (2));
                players.add (new Player (5));
                players.add (new Player (-3));
                players.add (new Player (1));
        
                Collections.sort(players, new Comparator<Player> () {
                    @Override
                    public int compare(Player o1, Player o2) {
                        final float distance1 = o1.getDistanceFrom();
                        final float distance2 = o2.getDistanceFrom();
                        return (int) Math.signum (distance1 - distance2);
                    }           
                });
                System.out.println(players);
            }
        }
        

        还有一个fiddle

        【讨论】:

        • 这是正确有效的。但是,有时我认为初学者更容易理解 Comparator 是否作为传统类实现(而不是内联定义)。我也没有看到使用 Math.signum 的好处(我在这个网站上见过几次)。为什么不直接返回差值(作为 int)?
        • @jahroy 您必须以某种方式将float 的差异转换为int。由于舍入的方式,您不能只使用(int) (a - b) - 您必须使用Math.signum
        • 很公平。现在我明白了。你每天都在这个网站上学到一些东西!为了记录,我已经赞成这个答案。
        猜你喜欢
        • 2014-05-03
        • 1970-01-01
        • 2011-07-16
        • 1970-01-01
        • 2011-05-21
        • 2014-06-04
        • 2011-05-01
        • 2018-10-16
        相关资源
        最近更新 更多