如何根据 ID、姓名或出生日期对保存人员的 TreeMap 或 ArrayList 进行排序?

发布于 2024-09-10 16:04:21 字数 2311 浏览 7 评论 0原文

我几乎尝试了所有方法,但似乎无法让我的清单自行排序。 这是一些代码:

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;

这些值用随机数填充。我的日期有日期格式。

我的 person 类中也有一个 toString 方法,但由于某种原因,当我尝试打印我的地图时,它给了我哈希码(这是哈希码,对吧?)Person@a62fc3。 这是 person 类中的 toString:

             public String toString()
    {

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

    }

我应该补充一点,我无法在 person 类中调用 toString 方法。因为它正在打印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());
        }
    }

输出: 人@10b30a7 人@1a758cb 人@1b67f74 人@69b332 人@173a10f 人@530daa 人@a62fc3 人@89ae9e 人@1270b73 人@60aeb0 人@16caf43 人@66848c 人@8813f2 人@1d58aae 人@83cc67 人@e09713 人@de6f34 人@156ee8e 人@47b480

谢谢

I have tried almost everything and I can't seem to get my lists to order themselves.
Here's some code:

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;

The values are filled with randoms. My date has a date format.

I also have a toString method inside my person class, but for some reason when I try to print my maps it gives me the hashcode (this is the hashcode right?) Person@a62fc3.
Here is my toString inside the person clasS:

             public String toString()
    {

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

    }

I should add that I am not able to call my toString method inside my person class. Because it is printing 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();

}

The commented code will work but the code calling the toString does not print what it should

Compare to method inside of my Person class:

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;

I can provide more code if it's needed.

Compare by name method and it's output. Should I make an arrayList to store my values in and then sort it in that?

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

Output:
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

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

霓裳挽歌倾城醉 2024-09-17 16:04:21

好吧,我无法指出确切的问题,我有一些建议。

地图未排序。

一般来说,Map 是没有排序的,因此您将无法对映射的键进行排序。如果您想对Map进行排序,请使用SortedMap接口。

尽可能使用泛型

Comparable 接口是泛型的。您可能应该实现 Comparable

compareTo() 方法应该如下所示:

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

然后您 com/docs/cd/E17409_01/javase/6/docs/api/java/util/Comparator.html" rel="nofollow noreferrer">Comparator可比较<人>

您需要查看 Comparator 接口以及 Comparable 接口。
您的 Person 应该以您通常希望对人员进行排序的方式实现比较。然后你应该编写一些Comparator的实现。

public classPersonNameComparator implements Comparator<Person> {

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

使用@Override 注释的重要性

每当您尝试重写超类的方法或实现接口方法时,始终使用@Override 注释非常重要。以下是一些关于为什么这是一个好主意的链接:

Well, I can't pinpoint the exact problem, I have a few suggestions.

Maps aren't sorted.

In general, an Map is not sorted, so you will not be able to sort the keys of the map. If you want to sort the Map use the SortedMap interface.

Use Generics when possible

The Comparable interface is generic. You should probably be implementing Comparable<Person>

Then your compareTo() method should look like this:

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

The difference between Comparator<Person> and Comparable<Person>

You need to take a look at the Comparator interface as well as the Comparable interface.
Your Person should implement comparable in that way that you usually want a person to be sorted. Then you should write some implementations of Comparator.

public classPersonNameComparator implements Comparator<Person> {

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

The importance of using the @Override annotation

It is important to always use the @Override annotation whenever you are trying to override a method of a super class or implement an interface method. The following are a few links regarding why this is a good idea:

夏天碎花小短裙 2024-09-17 16:04:21

我看到的一个问题是 TreeMap排序,而不是按值排序。您的 compareTo 将不会用于树的排序,因为它是地图中的值。由于地图中的键是 id,因此树中的项目应按人员的 id 排序。

你怎么知道地图没有排序?你能给我们看一些输出来证明事实并非如此吗?在将 Person 放入地图后,您是否有机会更改其 ID?

哦,与 personMap 相比,names 是什么?另外,id真的是从1开始连续的吗?这段代码输出了什么:

for (Person person : peopleMap.values()) {
    System.out.println(person);
}

One issue that I see is that TreeMap sorts by key not by value. Your compareTo will not be used in the sorting of the tree since it is the value in the map. Since the key in the map is the id the the items in the tree should be sorted by the id of the person.

How do you know that the map isn't sorted? Can you show us some output that shows that it is not? Are you by any chance changing the ID of the Person after it gets put into the map?

Oh, and what is names compared to personMap? Also, are the ids really contiguous starting from 1? What does this code spit out:

for (Person person : peopleMap.values()) {
    System.out.println(person);
}
獨角戲 2024-09-17 16:04:21

您是否使用 @Override 方法来确保您实际上覆盖了 toString 方法?看起来它仍然打印出默认的 toString() (即指向对象的指针的值)。

did you use the @Override method to make sure that you are actually overriding the toString method? It looks like it is still printing out the default toString() (ie the value of the pointer to the object).

铜锣湾横着走 2024-09-17 16:04:21

请参阅:比较器 API。

“当且仅当 (compare((Object)e1, (Object)e2)==0) 与 e1 具有相同的布尔值时,比较器 c 对一组元素 S 施加的排序才被认为与 equals 一致。对于 S 中的每个 e1 和 e2,等于((Object)e2)。”

我在您的 Person 类中没有看到 equals 方法。 equals 的默认实现比较同一性。如果重写 equals,则必须定义 hashCode 2。

还有这个问题: 一致的 Equals() 结果,但不一致的 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>]

see : comparator API.

"The ordering imposed by a Comparator c on a set of elements S is said to be consistent with equals if and only if (compare((Object)e1, (Object)e2)==0) has the same boolean value as e1.equals((Object)e2) for every e1 and e2 in S."

I don't see an equals method in your Person class. The default implementation of equals compares identity. And if you override equals, you must define hashCode two.

And this question : Consistent Equals() results, but inconsistent TreeMap.containsKey() result

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

Outputs :

[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>]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文