有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java理解排序和未排序ArrayList<Object>

我在做一个小项目,遇到了一个问题(?)我真的无法解释。这是我的代码:

==Main=====

    Beacon b1 = new Beacon("192.168.0.12", 72.0);
    Beacon b4 = new Beacon("192.168.0.13", 72.0);
    Beacon b2 = new Beacon("192.168.0.24", 84.0);
    Beacon b3 = new Beacon("192.168.0.5", 64.0);
    ArrayList<Beacon> alBeacons = new ArrayList();

    alBeacons.add(b4);
    alBeacons.add(b2);
    alBeacons.add(b1);
    alBeacons.add(b3);

    Room room = new Room("Testroom", alBeacons);

===信标====

public class Beacon {
String sIP;
private int ID = 0;
private Double RSSi;



public Beacon(String sIP, double RSSi){
    this.sIP = sIP;
    this.RSSi = RSSi;
    setID();
}

private void setID(){
    String sTemp[] = sIP.split("\\.");
    this.ID = Integer.parseInt(sTemp[sTemp.length-1]);

}

public String getsID(){
    return String.valueOf(ID);
}

public int getID(){
    return ID;
}
}

房间====

    public Room(String sName, ArrayList<Beacon> alBeacons){
    System.out.println("Unsorted: " + alBeacons.hashCode());
    for(Beacon b: alBeacons){
        System.out.println(b.getID());
    }
    alBeacons.sort(new Comparator<Beacon>() {

        @Override
        public int compare(Beacon o1, Beacon o2) {
            return o1.getID() - o2.getID();
        }
    });
    System.out.println("Sorted: " + alBeacons.hashCode());
    for(Beacon b: alBeacons){
        System.out.println(b.getID());
}

}

现在我的问题是,在未排序状态下,无论信标如何插入ArrayList,我总是得到相同的HashCode(),1498918675。一旦我对它们进行排序,就会得到一个不同的哈希代码,这很有意义。但现在的问题是,根据ArrayList最初的排序方式,排序后我会得到不同的哈希代码。这是我们的天性。sort(),还是我对实数排序的修复破坏了它

编辑:以下是一些输出示例:

Unsorted: 1498918675
13
24
12
5
Sorted: 341854239
5
12
13
24

Unsorted: 1498918675
24
5
12
13
Sorted: 638040239
5
12
13
24

Unsorted: 1498918675
12
5
24
13
Sorted: 1060992495
5
12
13
24

共 (2) 个答案

  1. # 1 楼答案

    一个List的hashCode必须是(接口内的契约):

    int hashCode = 1;
    for (E e : list)
        hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
    return hashCode;
    

    因此,元素的顺序在确定哈希代码时很重要:为已排序或未排序的列表获取不同的哈希代码是正常的

    然而,您声明,“根据ArrayList最初的排序方式,排序后我会得到一个不同的哈希代码”:因此基本上您声明:

    • 案例1: 从[b,a,c]开始,排序为[a,b,c],得到哈希码X
    • 案例2: 从[c,b,a]开始,排序为[a,b,c],得到哈希代码Y

    如果Beacon类的hashcode方法依赖于Beacon的字段,则不应该发生这种情况。您没有重写hashCode,因此它是基本的实现,通常通过将对象的内部地址转换为int“(来自javadoc)来实现

    要解决您的问题,您应该在Beacon内定义自己的hashCode

    public int hashCode() {
        final int prime = 31;
        int res = (sIP != null) ? sIP.hashCode() : 1;
        res = res * prime + ID;
        return res * prime + Double.hashCode(RSSi);
    }
    
  2. # 2 楼答案

    根据内容和顺序计算列表的哈希代码

     public int hashCode() {
            int hashCode = 1;
            for (E e : this)
                hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
            return hashCode;
        }