0

私のEntityクラスには、HashMapがあります。今、私はこのマップの選択を作成して、オブジェクトを選択できるようにしようとしています。そこで、次のクラスを作成しました。

HorseConverter:

@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を書いても違いはありません。

編集:これが私のハッシュであり、HorseEntityからのコードに相当します:

@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() をオーバーライドしましたか?

コンバーターを機能させるには、equals() をオーバーライドする必要があります。これを行わないと、Horse() の同じインスタンスへの 2 つの参照のみが等しくなり、まったく同じ状態を持つ 2 つの別個のインスタンスではなくなります。コレクションは比較する暗黙のコピーを作成するため、この場合、ヒープ上に単一のインスタンスはありません。

equals() オブジェクトの引数は、Horse() ではなく Object() であることを忘れないでください。

hashcode() をオーバーライドしない場合、ハッシュコードは Horse のインスタンスごとに異なります。これは、HashMap で Horse を見つけるために比較するインスタンスが複数あるため、HashMap で Horse が論理的に同等であっても、比較に適した 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;
}

本当に を使用したい場合は、Mapを返す必要があります。は のニックネームです。Map<String, Horse>StringHorse

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

値を使用する場合はMap、忘れずに を削除してくださいvar:

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

マップのキーはオプション ラベルになり、マップの値はオプション値になります。


具体的な問題とは関係なく、aHashMapは本質的に順序付けされていません。ドロップダウン項目を挿入順に表示したい場合は、代わりにLinkedHashMap.

于 2013-01-17T15:49:02.417 に答える