5

Lists全体を変換するより良い方法がないか、またはCollections次のコード例に示す方法がないかどうか疑問に思っています。

public static List<String> getAllNames(List<Account> allAccounts) {
        List<String> names = new ArrayList<String>(allAccounts.size());
        for (Account account : allAccounts) {
            names.add(account.getName());
        }
        return names;
    }

このようなものを作るたびmethodに、もっと良い方法はないかと考え始めます。私の最初の考えは、おそらくいくつかのgenericsとを使用したソリューションを作成することreflectionsですが、これはおそらく少し大きすぎて、パフォーマンスに関しては少し遅いのでしょうか?

4

6 に答える 6

6

GoogleのGuavaライブラリをご覧ください

このような何かがそれを行う必要があります

final List<String> names = Lists.transform(myObjs, new Function<MyObject, String>() {
    public String apply(final MyObject input) {
        return input.getName();
    }
});
于 2012-12-04T14:31:38.940 に答える
5

Guavaには、より機能的なアプローチがあります。

return FluentIterable.from(allAccounts).transform(new Function<Account,String>(){
    public String apply(Account account){return account.getName();}
}).toImmutableList()

もちろん、それは本質的に同じことをします。

ところで:この回答とRNJの回答の違いは、私の場合はリストが1回作成されるのに対し、他の回答ではライブビューであるということです。どちらのバージョンも有効ですが、シナリオが異なります。

于 2012-12-04T14:30:49.700 に答える
2

私の個人的なライブラリには、まさにこの種の方法があります。

public static <TSource,TTarget> List<TTarget> castList(List<TSource> sourceList)
{
    List<TTarget> targetList = new ArrayList<TTarget>(sourceList.size());
    for (TSource t : sourceList) {
        //This will throw a ClassCastException if the types are not compatible
        //Be carefull
        targetList.add((TTarget)t);
    }
    return targetList;
}

コンパイラがTTargetの型を推測するため、使用法は非常に簡単です。

List<Object> objects = new ArrayList<Object>();
objects.add("One");
objects.add("Two");

List<String> strings = castList(objects);

パフォーマンスに関して:ここではジェネリックを使用しても問題ないと思います。しかし、アレイ全体をコピーする必要性は別の話です。

于 2012-12-04T14:43:13.553 に答える
0

簡単な方法がありますが、タイプセーフではありません

List<A> a = new ArrayList<A>();
List<B> b = (List)a;

ただし、クラスの toString() メソッドの実装をオーバーライドして、getName() 値を返す必要があります。しかし、型チェックはありません。

前述のように、もちろん代わりにループを実行して、すべてのオブジェクトで getName を呼び出すことができます

于 2012-12-04T14:32:55.303 に答える
0

Guava ライブラリのIterablesおよびクラスを使用してみてください。を使用Functionして新しいタイプの を作成できます。Iterable

Iterable<String> newTypeIterable = Iterables.transform(oldTypeIterable, new Function<MyDataType, String> () {
   @Override
   public String apply(MyDataType from)
   {
     return from.getName();
   }
});

Listsクラスでもこれを行うことができます!

于 2012-12-04T14:34:01.397 に答える
0

これ以上の方法はありません。キャスティングは難しく危険なものです。あなたの例では、文字列を MyDataType に、またはその逆にキャストすることはできませんよね? これらがより頻繁に必要な場合は、ある種の toStringList()-Method を使用して独自の List-Implementation を作成することもできます。

于 2012-12-04T14:29:27.757 に答える