【问题标题】:How to sort objects in ArrayList by 2 float attributes?如何通过 2 个浮点属性对 ArrayList 中的对象进行排序?
【发布时间】:2019-11-05 10:32:32
【问题描述】:

我的目标是对一个类的数组列表进行排序

 public class AnimSprite
    {
    float x,y,z;
    //...//
    }

ArrayList<AnimSprite> listofsprites = new ArrayList<AnimSprite>();

    //...//

list.add( new AnimSprite(1f,10f,0f) );      //x,y,z
list.add( new AnimSprite(15f,25f,1f) );
list.add( new AnimSprite(30f,-62f,0f) );
list.add( new AnimSprite(150f,-62f,2f) );
list.add( new AnimSprite(55f,-65f,0f) );

    //...//

那我当然循环画了

for (AnimSprite s: listofsprites) { s.draw();}

在绘制指令之前,我们如何对数组列表进行排序? (按 y 升序然后 z 升序排列)

例如预期结果:

obj0 -> AnimSprite(55f,-65f,0f)
obj1 -> AnimSprite(30f,-62f,0f) 
obj2 -> AnimSprite(1f,10f,0f)
obj3 -> AnimSprite(15f,25f,1f)
obj4 -> AnimSprite(150f,-62f,2f)

目前,如下所示,我按 y 和 z 升序排序,但我不确定它是否是最先进的?

  public static class AnimSprite implements Comparable<AnimSprite >
    {
    //...//
   Override
       public int compareTo(AnimSprite o)
    {
        float result = this.z - o.z;
        if (result == 0f) result = this.y - o.y;
        return ((int)(result));
        }   

【问题讨论】:

  • 我建议您使用Comparator接口自己尝试:docs.oracle.com/javase/7/docs/api/java/util/Comparator.html。如果您仍然有困难,请回复,我们可以解决。
  • 这不是主题本身,但我建议尽可能使用接口而不是类,例如: ArrayList listofsprites = new ArrayList();应该是 List listofsprites = new ArrayList();
  • 谢谢,但最后一点是按 2 个浮点数排序
  • Collection.sort(list)
  • 请注意按2个浮点属性正确排序

标签: java sorting arraylist


【解决方案1】:

您可以使用Collection.sort(list) 对您的ArrayList 进行排序,但AnimSprite 必须实现Comparable 接口才能让sort 方法知道如何比较两个AnimSprite 对象。

public class AnimSprite implements Comparable
{
    float x,y,z;
    //...//

   @Override
   public int compareTo(AnimSprite o)
{
    float result = this.z - o.z;
    if (result == 0f) result = this.y - o.y;
    return ((int)(result));
    }   
}

ArrayList<AnimSprite> listofsprites = new ArrayList<AnimSprite>();

    //...//

listofsprites.add( new AnimSprite(1f,10f,0f) );      //x,y,z
listofsprites.add( new AnimSprite(15f,25f,1f) );
listofsprites.add( new AnimSprite(30f,-62f,0f) );
listofsprites.add( new AnimSprite(150f,-62f,2f) );
listofsprites.add( new AnimSprite(55f,-65f,0f) );

//...//

Collection.sort(listofsprites);

for (AnimSprite s: listofsprites) { s.draw();}

另一种解决方案是使用重载方法sort 接受Comparator 实现作为第二个参数,并使用Lambda expression 编写更少的代码:

Collections.sort(listofsprites, (s1, s2) -> {
    float result = s1.z - s2.z;
    if (result == 0f) result = s1.y - s2.y;
    return ((int)(result));
});

【讨论】:

  • 谢谢,我用类似的界面向前迈进了。但是我想不出最简单的 2 个属性排序方式(例如 y 和 z)?
  • @Chronoslog 查看我的编辑:我在 lambda 中实现了您的比较逻辑
  • 我会选择第一个选项,响应时间更高效 M1> 291537 nanoSecs (@Override ... compareTo(AnimSprite o)) 而 M2> 48145753 nanoSecs ( Collections.sort(listofsprites, (s1, s2) -> ...)
【解决方案2】:

有两种简单的方法可以实现您想要的。两者都归结为数组的元素应该彼此“可比”。

选项 1:

AnimSprite 中实现Comparable 接口。定义 compareTo 方法(因为你实现了接口,你必须这样做)依赖 2 个数字进行比较。

然后使用:

Collections.sort(yourArray);

选项 2:

当你不能真正改变AnimSprite类时可以使用。在这种情况下,您可以实现Comparator 接口,有效地将比较逻辑外部化:

Collections.sort(yourArray, new Comparator<AnimSprite> {
     public int compare(AnimSprite s1, AnimSprite s2) {
                ...
     }
 });

当然,如果你使用的是 java 8+,你也可以使用 lambda

【讨论】:

  • 抱歉的问题不是如何对 java 对象进行排序,而是特定于 2 个浮点数(不是整数、字符串或其他...)
【解决方案3】:

是的。你也可以这样做:

    Collections.sort(list,
            Comparator.comparing((AnimSprite a) -> a.z)
                    .thenComparing((AnimSprite a) -> a.y));

【讨论】:

  • 谢谢它有效,但执行时间接缝更长:M1> 291537 nanoSecs (@Override ... compareTo(AnimSprite o)) M2> 48145753 nanoSecs (Collections.sort(listofsprites, (s1, s2) -> ...) M3> 48187767 nanoSecs ( Comparator.comparing((AnimSprite a) -> a.z ....thenComparing ...)
猜你喜欢
  • 1970-01-01
  • 2011-03-21
  • 1970-01-01
  • 1970-01-01
  • 2019-09-24
  • 1970-01-01
  • 2012-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多