0

在我的实体类中,我有一个 HashMap。现在我正在尝试创建此 Map 的 Select 以便能够选择对象。所以我创建了以下类:

马转换器:

@Named
public class HorseConverter implements Converter{

    @EJB
    private HorseBean bean;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        return bean.getHorse(Long.valueOf(value));
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        if(!(value instanceof Horse)){
            throw new ConverterException(new FacesMessage("Object is not a Horse"));
        } else {
            Horse h = (Horse) value;
            return Long.toString(h.getId());
        }
    }

}

种族实体:

public Map<Horse, Integer> getHorses() {
        return horses;
    }

    public void setHorses(HashMap<Horse, Integer> horses) {
        this.horses = horses;
    }

而我的观点:

Horse:
<h:selectOneMenu value="#{betController.horse}" converter="#{horseConverter}">
    <f:selectItems value="#{raceController.selectedRace.horses}" var="h" itemLabel="#{h.nickName}" itemValue="#{h}"/>
</h:selectOneMenu>

似乎我得到的价值不是 Horse 的实例。我检查了以下链接: https ://stackoverflow.com/tags/selectonemenu/info所以看来密钥被自动用作值。但即使写 h.key 也没有什么不同。

编辑:这是我的马实体的哈希和等于代码:

@Override
    public int hashCode() {
        int hash = 7;
        hash = 97 * hash + (int) (this.id ^ (this.id >>> 32));
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Horse other = (Horse) obj;
        if (this.id != other.id) {
            return false;
        }
        return true;
    }
4

2 回答 2

0

您是否在 Horse() 对象中覆盖了 hashcode() 和 equals()?

您的 Converter 需要覆盖 equals() 才能工作。如果您不这样做,则只有对同一 Horse() 实例的两个引用是相等的,而不是两个具有完全相同状态的单独实例。集合创建一个隐式副本进行比较,因此在这种情况下,堆上不会有单个实例。

不要忘记 equals() 对象中的参数是 Object(),而不是 Horse()。

如果您不覆盖 hashcode(),则每个 Horse 实例的 hashcode 都会不同。这意味着您将很难找到合适的 Horse 进行比较,即使您的 Horses 在逻辑上是等价的,因为同样,您将有多个实例进行比较,以便在 HashMap 中找到您的 Horse。

有关详细信息,请参阅Joshua Bloch 撰写的 Effective Java 的这一章。

于 2013-01-17T15:43:27.050 回答
0

你不能var在一个Map值上使用。<f:selectItems>仅当您使用而List<Horse>不是Map<Horse, Integer>.

public List<Horse> getHorses() {
    return horses;
}

如果你真的想使用 a Map,那么你应该返回 a Map<String, Horse>,其中String是 的昵称Horse

public Map<String, Horse> getHorses() {
    return horses;
}

如果使用Map值,请不要忘记删除var

<f:selectItems value="#{raceController.selectedRace.horses}" />

地图的键成为选项标签,地图的值成为选项值。


与具体问题无关HashMap,a本质上是无序的。如果要按插入顺序显示下拉项目,请使用LinkedHashMap.

于 2013-01-17T15:49:02.417 回答