简体   繁体   English

如何通过 2 个浮点属性对 ArrayList 中的对象进行排序?

[英]How to sort objects in ArrayList by 2 float attributes?

I aim to sort an arraylist of a class我的目标是对 class 的 arraylist 进行排序

 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) );

    //...//

Then of course I loop to draw it然后当然我循环绘制它

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

Before draw instruction, how could we sort the array list?在绘制指令之前,我们如何对数组列表进行排序? (ordered by y ascending and then z ascending) (按 y 升序然后 z 升序排序)

Eg expected result:例如预期结果:

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)

for the moment, as below, I sort ascending by y and z but I am not sure it is state of art?目前,如下所示,我按 y 和 z 升序排序,但我不确定它是否是艺术的 state?

  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));
        }   

You can use Collection.sort(list) to sort your ArrayList but AnimSprite must implement the Comparable Interface to let the sort method to know how to compare two AnimSprite objects.您可以使用Collection.sort(list)ArrayList进行排序,但AnimSprite必须实现Comparable Interface 以让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();}

Another solution is to use the overloaded method sort that accept the Comparator implementation as second argument, and use the Lambda expression to write less code:另一种解决方案是使用接受Comparator实现作为第二个参数的重载方法sort ,并使用Lambda expression来编写更少的代码:

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

There are two simple ways to achieve what you want.有两种简单的方法可以实现您想要的。 Both boil down to the idea that the elements of the array should be "comparable" to each other.两者都归结为数组的元素应该彼此“可比”的想法。

Option 1:选项1:

Implement Comparable interface in AnimSprite .AnimSprite中实现Comparable接口。 Define compareTo method (that you'll have to since you implement the interface) to rely on 2 numbers for comparison.定义compareTo方法(因为您实现了接口,所以您必须这样做)以依赖 2 个数字进行比较。

Then use:然后使用:

Collections.sort(yourArray);

Option 2:选项 2:

Can be used when you can't really change AnimSprite class.当您无法真正更改AnimSprite class 时可以使用。 In this case you can implement the Comparator interface effectively externalizing comparison logic:在这种情况下,您可以实现Comparator接口,有效地将比较逻辑外部化:

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

Of course you can also use lambda if you're using java 8+当然,如果您使用 java 8+,您也可以使用 lambda

Yes.是的。 You can also do something like this:你也可以这样做:

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

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

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