24

私は次のようなことをしたいと思います:

ArrayList<CustomObject> objects = new ArrayList<CustomObject>();
...
DozerBeanMapper MAPPER = new DozerBeanMapper();
...
ArrayList<NewObject> newObjects = MAPPER.map(objects, ...); 

仮定:

<mapping>
  <class-a>com.me.CustomObject</class-a>
  <class-b>com.me.NewObject</class-b>   
    <field>  
      <a>id</a>  
      <b>id2</b>  
    </field>  
</mapping>

私は試した :

ArrayList<NewObject> holder = new ArrayList<NewObject>();
MAPPER.map(objects, holder);

ただし、ホルダー オブジェクトは空です。また、運がなければ2番目の引数を変更して遊んだ...

4

8 に答える 8

32

引用するには:

「ネストされたコレクションは自動的に処理されますが、トップレベルのコレクションを繰り返す必要があるのは正しいです。現在、これを処理するためのより洗練された方法はありません。」

誰かがあなたのコードベースにループ構造なしでそれを行う方法を考え出しました、しかし私はあなたのコードにそれを置くことはただ簡単である(そしてより読みやすく/維持可能である)と思います。うまくいけば、彼らはこの能力を遅かれ早かれ追加するでしょう。

于 2009-08-31T18:18:02.757 に答える
9

私は同様の問題に直面し、そのようなマッピングを実行する必要があるたびに反復することを避けるために、一般的なユーティリティ メソッドを使用することにしました。

public static <T, U> List<U> map(final Mapper mapper, final List<T> source, final Class<U> destType) {

    final List<U> dest = new ArrayList<>();

    for (T element : source) {
        dest.add(mapper.map(element, destType));
    }

    return dest;
}

使用法は次のようになります。

    final List<CustomObject> accounts..... 
    final List<NewObject> actual = Util.map(mapper, accounts, NewObject.class);

おそらく、これはさらに単純化される可能性があります。

于 2011-12-28T03:02:41.963 に答える
5

何が起こっているかというと、型消去に噛まれているということです。実行時に、Java はArrayList.class. CustomObjectとのタイプが存在しないため、Dozer は ではなくをNewObjectマッピングしようとしてjava.util.ArrayListいます。CustomObjectNewObject

何が機能するはずですか(完全にテストされていません):

List<CustomObject> ori = new ArrayList<CustomObject>();
List<NewObject> n = new ArrayList<NewObject>();
for (CustomObject co : ori) {
    n.add(MAPPER.map(co, CustomObject.class));
}
于 2009-08-31T17:58:13.887 に答える
3

あなたはこのようにすることができます:

public <T,S> List<T> mapListObjectToListNewObject(List<S> objects, Class<T> newObjectClass) {
final List<T> newObjects = new ArrayList<T>();
for (S s : objects) {
    newObjects.add(mapper.map(s, newObjectClass));
}
return newObjects;

}

そしてそれを使用します:

ArrayList<CustomObject> objects = ....
List<NewObject> newObjects = mapListObjectToListNewObject(objects,NewObject.class);
于 2014-04-16T18:19:31.553 に答える
2

そのユースケースのために、私はかつて小さなヘルパークラスを書きました:

import java.util.Collection;

/**
 * Helper class for wrapping top level collections in dozer mappings.
 * 
 * @author Michael Ebert
 * @param <E>
 */
public final class TopLevelCollectionWrapper<E> {

    private final Collection<E> collection;

    /**
     * Private constructor. Create new instances via {@link #of(Collection)}.
     * 
     * @see {@link #of(Collection)}
     * @param collection
     */
    private TopLevelCollectionWrapper(final Collection<E> collection) {
        this.collection = collection;
    }

    /**
     * @return the wrapped collection
     */
    public Collection<E> getCollection() {
        return collection;
    }

    /**
     * Create new instance of {@link TopLevelCollectionWrapper}.
     * 
     * @param <E>
     *            Generic type of {@link Collection} element.
     * @param collection
     *            {@link Collection}
     * @return {@link TopLevelCollectionWrapper}
     */
    public static <E> TopLevelCollectionWrapper<E> of(final Collection<E> collection) {
        return new TopLevelCollectionWrapper<E>(collection);
    }
}

次に、次の方法でドーザーを呼び出します。

private Mapper mapper;

@SuppressWarnings("unchecked")
public Collection<MappedType> getMappedCollection(final Collection<SourceType> collection) {
    TopLevelCollectionWrapper<MappedType> wrapper = mapper.map(
            TopLevelCollectionWrapper.of(collection),
            TopLevelCollectionWrapper.class);

    return wrapper.getCollection();
}

mapper.map(...)唯一の欠点: Dozers Mapperインターフェースがジェネリック型を処理しないため、「チェックされていない」警告が表示されます。

于 2011-05-09T13:09:56.417 に答える
2

dozer マッパーを拡張する独自のマッパー クラスを実装できます。例: dozer マッパーにメソッドを追加するインターフェースを作成します。

public interface Mapper extends org.dozer.Mapper {
    <T> List<T> mapAsList(Iterable<?> sources, Class<T> destinationClass);
}

次のステップ: 上記のインターフェースを実装して、独自の Mapper クラスを作成します。

以下のメソッドを実装クラスに追加します。

public class MyMapper implements Mapper {
    @Override
    public <T> List<T> mapAsList(Iterable<?> sources, Class<T> destinationClass) {
        //can add validation methods to check if the object is iterable
        ArrayList<T> targets = new ArrayList<T>();
        for (Object source : sources) {
            targets.add(map(source, destinationClass));
        }
        return targets;
    }
    //other overridden methods.
}

お役に立てれば

于 2016-05-25T07:42:32.313 に答える
2

実際には改善ではなく、 Guavaのおかげで達成できるシンタックス シュガーのようなものです (そして、 Apache Commonsでも同様のことが可能である可能性が最も高いです):

final List<MyPojo> mapped = Lists.newArrayList(Iterables.transform(inputList, new Function<MyEntity, MyPojo>() {
    @Override public MyPojo apply(final MyEntity arg) {
        return mapper.map(arg, MyPojo.class);
    }
}));

これは、他の回答で示唆されているように、一般的な関数に変換することもできます。

于 2012-04-19T10:22:15.230 に答える