0

プロジェクトで BetterBeanBindings を使用していますが、キーが文字列ではない Map に対してバインディングを実行できれば素晴らしいと思います。

状況を説明する例を見てみましょう。

public class Bean {
    // ...
    private Map<String, AnotherObject> mapOne;
    private Map<SomeObject, AnotherObject> mapTwo;
    // ...

    public Map<String, AnotherObject> getMapOne() {
        return this.mapOne;
    }

    public void setMapOne(Map<String, AnotherObject> mapOne) {
        Map<String, AnotherObject> oldMapOne = this.mapOne;
        this.mapOne = mapOne;
        this.propertyChangeSupport.firePropertyChange("mapOne", oldMapOne, mapOne);
    }

    public Map<SomeObject, AnotherObject> getMapTwo() {
        return this.mapTwo;
    }

    public void setMapTwo(Map<SomeObject, AnotherObject> mapTwo) {
        Map<SomeObject, AnotherObject> oldMapTwo = this.mapTwo;
        this.mapTwo = mapTwo;
        this.propertyChangeSupport.firePropertyChange("mapTwo", oldMapTwo, mapTwo);
    }

    // ...
}

BBB は、キーが文字列であるマップに対してバインドを行うことができます (標準的な解析を行う基本型でさえないことを覚えていれば、数字に対しても可能です)。

Bean bean;
// ...
Bindings.createAutoBinding(UpdateStrategy.READ_WRITE
        bean, BeanProperty.create("mapOne.xxx"),
        whateverBean, whateverProperty);

bean.getMapOne().get("xxx")これにより、結果が5 番目と 4 番目のパラメーターで指定されたオブジェクトの指定されたプロパティに適切にバインドされます。

しかし、同じことを試してみるとmapTwo

Bindings.createAutoBinding(UpdateStrategy.READ_WRITE
        bean, BeanProperty.create("mapTwo.xxx"),
        whateverOtherOrNotBean, whateverOtherOrNotProperty);

bean.getMapTwo().get("xxx")それはプロパティの定義で提供されたものであり、返さmapTwoれる ではない可能性があるため、バインディングは解決しようとします。バインディングは、解決のためにプロパティから必要なオブジェクトに変換する方法を知る必要がないため、これは理にかなっています。StringnullString

これを行うオプションはありますか?コンバーターを使用して何らかの回避策があるのではないでしょうか?

4

1 に答える 1

0

すべてのケースで機能するわけではありませんが、非常に一般的な小さな回避策を実行しました。

Map<K, V>タイプの値に応答できる を使用するKか、メイン マップStringをサポートします。Map<String, V>

StringBackedMap:

import java.util.Map;
import java.util.Set;

public interface StringBackedMap<K, V> extends Map<K, V> {

    public V get(String key);

    public boolean containsKey(String key);

    public Set<Entry<String, V>> backerEntrySet();

    public Set<String> backerKeySet();

}

StringBackedHashMap:

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class StringBackedHashMap<K, V> extends HashMap<K, V> implements StringBackedMap<K, V> {

    private static final long serialVersionUID = 1L;

    private Map<String, V> backerMap;

    public StringBackedHashMap() {
        super();

        init();
    }

    public StringBackedHashMap(int capacity) {
        super(capacity);

        init();
    }

    public StringBackedHashMap(int capacity, float loadFactor) {
        super(capacity, loadFactor);

        init();
    }

    public StringBackedHashMap(Map<? extends K, ? extends V> map) {
        super(map);

        init();

        putAll(map);
    }

    private void init() {
        this.backerMap = new HashMap<String, V>();
    }

    @Override
    public V get(String key) {
        return this.backerMap.get(key);
    }

    @Override
    public V get(Object key) {
        V value = super.get(key);

        if (value == null) {
            value = this.backerMap.get(key.toString());
        }

        return value;
    }

    @Override
    public boolean containsKey(String key) {
        return this.backerMap.containsKey(key);
    }

    @Override
    public boolean containsKey(Object key) {
        return super.containsKey(key) || this.backerMap.containsKey(key);
    }

    @Override
    public Set<String> backerKeySet() {
        return this.backerMap.keySet();
    }

    @Override
    public Set<Entry<String, V>> backerEntrySet() {
        return this.backerMap.entrySet();
    }

    @Override
    public V put(K key, V value) {
        V oldValue = super.put(key, value);

        this.backerMap.put(key.toString(), value);

        return oldValue;
    }

    @Override
    public void putAll(Map<? extends K, ? extends V> map) {
        super.putAll(map);

        if ((map != null) && (!map.isEmpty())) {
            for (Entry<? extends K, ? extends V> entry : map.entrySet()) {
                this.backerMap.put(entry.getKey().toString(), entry.getValue());
            }
        }
    }

    @Override
    public V remove(Object key) {
        V oldValue = super.remove(key);

        this.backerMap.remove(key.toString());

        return oldValue;
    }

    @Override
    public void clear() {
        super.clear();

        this.backerMap.clear();
    }

}
于 2013-03-15T10:59:19.673 に答える