Невозможно правильно сравнить организмы с сопоставимым интерфейсом - Java - PullRequest
0 голосов
/ 13 февраля 2020

Итак, у меня есть небольшой проект «Виртуальный мир» в Java, в котором есть четыре животных (они расширяют класс Организм). У каждого из них (Антилопа, Лиса, Черепаха, Волк) есть поля Инициатива, Сила и Возраст (все целые). Я хочу поместить их в массив, а затем отсортировать их с наивысшей Инициативой сверху, и если инициатива одинакова для обоих животных - чем старше, тем выше. Чтобы сравнить их, мой абстрактный класс «Организм» реализовал интерфейс Comparable, и я переопределил метод compareTo, поэтому он выглядит следующим образом:

    @Override
public int compareTo(Organism anotherOrganism) {
    int compareValue = 0;

    if (this.getInitiative() > anotherOrganism.getInitiative()){
        compareValue = 1;
    } else if (this.getInitiative() < anotherOrganism.getInitiative()){
        compareValue = -1;
    } else if (this.getInitiative() == anotherOrganism.getInitiative()){
        if (this.getAge() > anotherOrganism.getAge()){
            compareValue = 1;
        } else {
            compareValue = -1;
        }
    }
    return compareValue;
}

Я ввел этих животных в массив в следующем порядке (число в скобках указана их фактическая инициатива): Fox (7) -> Turtle (1) -> Antelope (4) -> Wolf (5) и затем использовали

        Collections.sort(organismList);

, ожидая, что это приведет к

 Fox, Wolf, Antelope, Turtle

вместо этого я получил

 Wolf, Antelope, Turtle, Fox

Что здесь пошло не так? Очевидно, что в Animals также реализован метод сравнения (они ссылаются на super.compareTo от Organism)

Редактировать: Да, поэтому ниже приведены советы о том, что код довольно хороший, я удалил любую Инициативу из животных (поле оставлено пустым), и я все еще получаю тот же вывод. Понятия не имею, почему ....

Ответы [ 3 ]

0 голосов
/ 13 февраля 2020

Вы можете сделать это так:

public class Demo {

    public static void main(String[] args) {
        final List<Organism> organisms = new ArrayList<>();

        // Each organism is created with initiative, strength and age
        organisms.add(new Antelope(4, 1, 1));
        organisms.add(new Fox(7, 2, 2));
        organisms.add(new Turtle(1, 3, 3));
        organisms.add(new Wolf(5, 4, 4));
        organisms.add(new Wolf(5, 4, 5));

        organisms.sort(Demo::sortByInitiative);

        for (Organism o : organisms) {
            System.out.println(o);
        }
    }

    private static int sortByInitiative(Organism o1, Organism o2) {
        int c = Integer.compare(o2.getInitiative(), o1.getInitiative());
        if (c != 0) {
            return c;
        }
        return Integer.compare(o2.getAge(), o1.getAge());
    }
}
0 голосов
/ 13 февраля 2020

При условии, что переменные членов инициативы и возраста опубликованы c (хотя вы можете заменить их получателями), вы можете добиться желаемой сортировки в одной строке кода

List<Organism> organisms = Arrays.asList(/* add your objects */);
organisms.sort(Comparator.comparing((Organism o) -> o.initiative, 
Comparator.reverseOrder()).thenComparing(o-> o.age, Comparator.reverseOrder()));

Полный пример приведен ниже

public class Quick {

    static class Organism{
        public String name;
        public int initiative;
        public int age;

        public Organism(String name, int initiative, int age) {
            this.name = name;
            this.initiative = initiative;
            this.age = age;
        }

        @Override
        public String toString() {
            return "Organism{" +
                    "name='" + name + '\'' +
                    ", initiative=" + initiative +
                    ", age=" + age +
                    '}';
        }
    }

    public static void main(String[] args) {
        List<Organism> orgs = Arrays.asList(
                new Organism("Fox", 1, 2),
                new Organism("Ant", 1, 3),
                new Organism("Mule", 2, 2)
        );

        orgs.sort(Comparator.comparing((Organism o) -> o.initiative,
        Comparator.reverseOrder()).thenComparing(o-> o.age, Comparator.reverseOrder()));
        orgs.stream().forEach(System.out::println);

    }

}
0 голосов
/ 13 февраля 2020

Я расширил код до Еда, готовая к употреблению . Он печатает ожидаемый.

[Organism$1Turtle, Organism$1Antelope, Organism$1Wolf, Organism$1Fox]

Код:

import java.util.*;

abstract class Organism implements Comparable<Organism> {
    public static void main(String[] args) throws Throwable {
        class Fox extends Organism {
            @Override public int getInitiative() {
                return 7;
            }
        }
        class Turtle extends Organism {
            @Override public int getInitiative() {
                return 1;
            }
        }
        class Antelope extends Organism {
            @Override public int getInitiative() {
                return 4;
            }
        }
        class Wolf extends Organism {
            @Override public int getInitiative() {
                return 5;
            }
        }
        List<Organism> organismList = Arrays.asList(
            new Fox(), new Turtle(), new Antelope(), new Wolf()
        );

        Collections.sort(organismList);

        System.err.println(organismList);
    }
    @Override public String toString() {
        return getClass().getName();
    }
    public abstract int getInitiative();
    public int getAge() {
        return 42;
    }
        @Override
public int compareTo(Organism anotherOrganism) {
    int compareValue = 0;

    if (this.getInitiative() > anotherOrganism.getInitiative()){
        compareValue = 1;
    } else if (this.getInitiative() < anotherOrganism.getInitiative()){
        compareValue = -1;
    } else if (this.getInitiative() == anotherOrganism.getInitiative()){
        if (this.getAge() > anotherOrganism.getAge()){
            compareValue = 1;
        } else {
            compareValue = -1;
        }
    }
    return compareValue;
}
}
...