' Однострочная вложенность для циклов '
Полагаю, что ответ на этот связанный вопрос поможет в целом для части вложенных циклов. Для ошибки имени с переменной «i» вы пытаетесь использовать переменную вне области ее определения.
Вы, по сути, имеете:
for x, y in zip
{
//where you are trying to use the variable i before it exists
}
for i in packs
{
}
Ради полноты.
Используя Java8
people.sort(Comparator.comparingInt(People::getId));
, если Вы хотите в descending order
people.sort(Comparator.comparingInt(People::getId).reversed());
Используйте вместо него People реализует Comparable
; это определяет естественный порядок для Людей
.
A Comparator
также может быть определен дополнительно, но People реализует Comparator
неверно.
Две перегрузки для Collections.sort
различны:
> void sort (List list)
Сопоставимые
объекты, используя их естественный порядок void sort (List list, Comparator super T> c)
Компаратор
Вы сбиваете их с толку, пытаясь отсортировать Компаратор
(опять же, поэтому не имеет смысла, что Человек реализует Comparator
). Опять же, чтобы использовать Collections.sort
, вам нужно, чтобы одно из следующих было истинным:
Comparable
(используйте сортировку с 1 аргументом
) Comparator
для типа должен быть предоставлен (используйте 2-args sort
) Кроме того, не используют необработанные типы в новом коде . Необработанные типы небезопасны и предоставляются только для совместимости.
То есть, вместо этого:
ArrayList peps = new ArrayList(); // BAD!!! No generic safety!
вы должны были использовать обобщенное объявление типа безопасного типа, например:
List<People> peps = new ArrayList<People>(); // GOOD!!!
Тогда вы обнаружите, что ваш код даже не компилируется !! Это было бы хорошо, потому что что-то не так с кодом ( Person
не реализует Comparable
), , но потому что вы использовали необработанный тип , компилятор не проверял это , и вместо этого вы получаете исключение ClassCastException
во время выполнения !!!
Это должно убедить вас всегда использовать типизированные универсальные типы в новом коде. Всегда.
Вы хотите реализовать Comparable, а не Comparator. Вам нужно реализовать метод compareTo. Однако вы близки к этому. Comparator - это "сторонняя" процедура сравнения. Comparable - это то, что данный объект можно сравнить с другим.
public int compareTo(Object obj1) {
People that = (People)obj1;
Integer p1 = this.getId();
Integer p2 = that.getid();
if (p1 > p2 ){
return 1;
}
else if (p1 < p2){
return -1;
}
else
return 0;
}
Примечание, вы можете захотеть проверить нули здесь для getId... на всякий случай.
В вашем примере класса есть пара неудобных вещей:
цена
и информация
(больше для объектов, а не для людей); В любом случае, вот демонстрация того, как использовать Comparator
:
public class ComparatorDemo {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Joe", 24),
new Person("Pete", 18),
new Person("Chris", 21)
);
Collections.sort(people, new LexicographicComparator());
System.out.println(people);
Collections.sort(people, new AgeComparator());
System.out.println(people);
}
}
class LexicographicComparator implements Comparator<Person> {
@Override
public int compare(Person a, Person b) {
return a.name.compareToIgnoreCase(b.name);
}
}
class AgeComparator implements Comparator<Person> {
@Override
public int compare(Person a, Person b) {
return a.age < b.age ? -1 : a.age == b.age ? 0 : 1;
}
}
class Person {
String name;
int age;
Person(String n, int a) {
name = n;
age = a;
}
@Override
public String toString() {
return String.format("{name=%s, age=%d}", name, age);
}
}
И эквивалентная демонстрация Java 8 будет выглядеть так:
public class ComparatorDemo {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Joe", 24),
new Person("Pete", 18),
new Person("Chris", 21)
);
Collections.sort(people, (a, b) -> a.name.compareToIgnoreCase(b.name));
System.out.println(people);
Collections.sort(people, (a, b) -> a.age < b.age ? -1 : a.age == b.age ? 0 : 1);
System.out.println(people);
}
}