Как я могу заказать TreeMaps или ArrayLists с людьми, основываясь на их ID, имени или дате рождения? - PullRequest
0 голосов
/ 19 июля 2010

Я перепробовал почти все, и я не могу заставить свои списки упорядочить себя.Вот некоторый код:

private List<Person> names = new ArrayList<Person>(); 
private Map<Integer, Person> peopleMap = new TreeMap <Integer, Person>();
for(int i = 0; i<20; i++)
        {
        Person personOne = new Person();
        peopleMap.put(personOne.id,personOne);
        names.add(personOne);
        }
        Collections.sort(names);
        run();
    }



My Person class:
public class Person implements Comparable {
    public String name;
    public int id;
    public Date birthdate;
    static int idRecord = 0;

Значения заполнены случайными числами.Моя дата имеет формат даты.

У меня также есть метод toString внутри моего класса person, но по какой-то причине, когда я пытаюсь распечатать свои карты, он дает мне хэш-код (это правильно хэш-код?) Person @a62fc3.Вот моя строка toString внутри человека clasS:

             public String toString()
    {

        char tab = '\t';
        return ("ID Number: "+id+tab+" Name: "+tab+name+tab+" Birthdate: "+(birthdate.toString()));

    }

Я должен добавить, что я не могу вызвать свой метод toString внутри моего класса person.Потому что это печать Person @ a62fc3.

public void sortByID()
{
    char tab = '\t';

    for (int i = 1; i<20; i++)
    System.out.println((peopleMap.get(i)).toString());
    //System.out.println("ID Number: "+(peopleMap.get(i).id)+tab+" Name: "+tab+peopleMap.get(i).name+tab+" Birthdate: "+peopleMap.get(i).birthdate);
    run();

}

Код с комментариями будет работать, но код, вызывающий toString, не печатает то, что должен

Сравните с методом внутри моего класса Person:

public int compareTo(Object obj) {
 Person o = (Person) obj; 
if (this.id == o.id) { return 0; }
 if (this.id > o.id) { return 1; } 
if (this.id < o.id) { return -1; } 
return 0;

Я могу предоставить больше кода, если это необходимо.

Сравните по имени метода и его вывод.Должен ли я создать arrayList для хранения своих значений и затем отсортировать их в этом виде?

    public void sortByName()
    {
//      char tab = '\t';

        for(int j = 1; j<20; j++)
        {
//          System.out.println("ID Number: "+(names.get(j).id)+tab+" Name: "+tab+peopleMap.get(j).name+tab+" Birthdate: "+peopleMap.get(i).birthdate);
            //Person p = names.get(j);
            System.out.println(names.get(j).toString());
        }
    }

Вывод: Person @ 10b30a7 Person @ 1a758cb Person @ 1b67f74 Person @ 69b332 Person @ 173a10f Person @ 530daa Person @ a62fc3 Person@ 89ae9e Person @ 1270b73 Person @ 60aeb0 Person @ 16caf43 Person @ 66848c Person @ 8813f2 Person @ 1d58aae Person @ 83cc67 Person @ e09713 Person @ de6f34 Person @ 156ee8e Person @ 47b480

Спасибо

Ответы [ 4 ]

0 голосов
/ 20 июля 2010

см .: API компаратора.

"Упорядочение, налагаемое Компаратором c на набор элементов S, называется согласованным в том и только в том случае, если (сравнение ((Объект) e1, (Объект)e2) == 0) имеет то же логическое значение, что и e1.equals ((Object) e2) для каждого e1 и e2 в S. "

Я не вижу метод equals в вашем классе Person.Реализация по умолчанию equals сравнивает идентичность.И если вы переопределяете equals, вы должны определить hashCode two.

И этот вопрос: Результаты согласованных равных (), но несовместимые результаты TreeMap.containsKey ()

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;


public class Person implements Comparable<Person> { 
    public final String name;
    public final int id;
    public final Date birthdate;

    public Person(int id, String name, Date birthdate) {
        this.id = id;
        this.name = name;
        this.birthdate = birthdate;
    }

    public static void main(String[] args) {    
        List<Person> list = new ArrayList<Person>();
        for (int i = 10; i > 0; i--) {
            list.add(new Person(i, "name" + String.valueOf(i), new Date()));
        }
        System.out.println(list);
        Collections.sort(list);
        System.out.println(list);
    }

    @Override
    public boolean equals(Object other) {
        if (!(other instanceof Person)) {
            return false;
        }
        return this.id == ((Person)other).id;
    }

    @Override
    public int hashCode() {
        return 41 * id;
    }

    @Override
    public String toString() {
        return "Person<" + id + ">";
    }

    @Override
    public int compareTo(Person other) {
        if (!(other instanceof Person)) {
            throw new IllegalArgumentException();
        }
        return this.id - ((Person)other).id;
    }
}

Выходы:

[Person<10>, Person<9>, Person<8>, Person<7>, Person<6>, Person<5>, Person<4>, Person<3>, Person<2>, Person<1>]
[Person<1>, Person<2>, Person<3>, Person<4>, Person<5>, Person<6>, Person<7>, Person<8>, Person<9>, Person<10>]
0 голосов
/ 19 июля 2010

Одна проблема, которую я вижу, заключается в том, что TreeMap сортирует по ключ не по значению.Ваш compareTo не будет использоваться при сортировке дерева, поскольку это значение на карте.Поскольку ключом на карте является идентификатор, элементы в дереве должны быть отсортированы по идентификатору человека.

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

О, и что такое names по сравнению с personMap?Кроме того, действительно ли идентификаторы смежны, начиная с 1?Что выдает этот код:

for (Person person : peopleMap.values()) {
    System.out.println(person);
}
0 голосов
/ 20 июля 2010

Вы использовали метод @Override, чтобы убедиться, что вы на самом деле переопределяете метод toString? Похоже, что он все еще распечатывает по умолчанию toString () (т.е. значение указателя на объект).

0 голосов
/ 19 июля 2010

Ну, я не могу точно определить точную проблему, у меня есть несколько предложений.

Карты не отсортированы.

Как правило, Map не сортируется, поэтому вы не сможете отсортировать ключи карты. Если вы хотите отсортировать Map, используйте интерфейс SortedMap.

Используйте Generics, когда это возможно

Интерфейс Comparable является общим. Вы, вероятно, должны реализовать Comparable<Person>

Тогда ваш compareTo() метод должен выглядеть следующим образом:

public int compareTo(Person p) {
    if (this.id > p.id) return 1;
    else if (this.id < p.id) return -1;
    else return 0;
}

Разница между Comparator<Person> и Comparable<Person>

Вам нужно взглянуть на интерфейс Comparator, а также на интерфейс Comparable.
Ваш Person должен реализовать сравнимо таким образом, что вы обычно хотите, чтобы человек был отсортирован. Затем вы должны написать несколько реализаций Comparator.

public classPersonNameComparator implements Comparator<Person> {

    public int compare(Person p1, Person p2) {
        return p1.name.compareTo(p2.name);
    }
}

Важность использования @Override аннотации

Важно всегда использовать аннотацию @Override всякий раз, когда вы пытаетесь переопределить метод суперкласса или реализовать метод интерфейса. Ниже приведены несколько ссылок о том, почему это хорошая идея:

...