使用java.util.Set时,Jackson bug(或功能!?) - mySet.size()始终为1

时间:2013-06-04 12:04:58

标签: json spring spring-mvc set jackson

我正在使用Jackson 2.2.0和Spring 3.2.0以及Hibernate 4.2.2。

我最近不得不通过POST将一组对象发送到服务器:

{"cancelationDate":"2013-06-05",
 "positions":[
   {"price":"EUR 12.00",
    "count":1},
   {"price":"EUR 99.00",
    "count":1}
 ]
}

我的课程如下:

public class Bill extends {
  LocalDate cancelationDate;

  Set<Position> positions;

  ...
}

public class Position { 
  Integer count;

  BigMoney price;

  @JsonIgnore
  Bill bill;

  ...
}

当我致电bill.getPositions().size()时,它会告诉我1


如果我使用List<Position>代替Set<Position>,则效果很好。那么Set的问题是什么?

谢谢:)

等于和hashCode:

public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = (int) (prime * result + ((id == null) ? 0 : id.hashCode()));
    return result;
}

public boolean equals(Object obj) {
    if (obj == this)
        return true;
    if (!(obj instanceof Position))
        return false;
    Position equalCheck = (Position) obj;
    if ((id == null && equalCheck.id != null) || (id != null && equalCheck.id == null))
        return false;
    if (id != null && !id.equals(equalCheck.id))
        return false;
    return true;
}   

2 个答案:

答案 0 :(得分:4)

由于Jackson反序列化位置的id为null,hashCode为不同的对象返回相同的值,而equals返回true。 Set不能包含相同的元素。修复你的equals / hashcode实现,一切都会正常工作。

建议新的hashCode / equals:

public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = (int) (prime * result + ((id == null) ? 0 : id.hashCode()));
    result = (int) (prime * result + ((price== null) ? 0 : price.hashCode()));
    return result;
}

public boolean equals(Object obj) {
    if (obj == this)
        return true;
    if (!(obj instanceof Position))
        return false;
    Position equalCheck = (Position) obj;
    if ((id == null && equalCheck.id != null) || (id != null && equalCheck.id == null))
        return false;
    if (id != null && !id.equals(equalCheck.id))
        return false;
    if ((price== null && equalCheck.price != null) || (price != null && equalCheck.price == null))
        return false;
    if (price!= null && !price.equals(equalCheck.idprice)
        return false;

    return true;
}   

答案 1 :(得分:1)

Set插入行时使用equals和hashcode方法,你有没有覆盖它们?

我还有杰克逊2.2.1(带地图)的一些错误,你应该升级到杰克逊2.2.2