Как отсортировать объекты в ArrayList по 2 атрибутам с плавающей точкой? - PullRequest
1 голос
/ 05 ноября 2019

Я хочу отсортировать массив класса

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

Ответы [ 3 ]

3 голосов
/ 05 ноября 2019

Вы можете использовать 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));
});
0 голосов
/ 05 ноября 2019

Да. Вы также можете сделать что-то вроде этого:

    Collections.sort(list,
            Comparator.comparing((AnimSprite a) -> a.z)
                    .thenComparing((AnimSprite a) -> a.y));
0 голосов
/ 05 ноября 2019

Есть два простых способа достичь того, что вы хотите. Оба сводятся к идее, что элементы массива должны быть «сопоставимы» друг с другом.

Вариант 1:

Реализация интерфейса Comparable в AnimSprite. Определите метод compareTo (который вам понадобится, поскольку вы реализуете интерфейс), чтобы полагаться на 2 числа для сравнения.

Затем используйте:

Collections.sort(yourArray);

Вариант 2:

Может использоваться, когда вы действительно не можете изменить AnimSprite класс. В этом случае вы можете реализовать интерфейс Comparator, эффективно экранирующий логику сравнения:

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

Конечно, вы также можете использовать лямбду, если вы используете java 8 +

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...