2016-05-19 6 views
-1

Guavaのコレクションutilsを使用してコードを記述し、コード断片を見てプレーンJava 7でコードを書き直したいと思うことがあります。なぜなら、IMHOはより簡潔で容易になるからです普通の古いJavaを使って読む。バニラのJava 7で、それは次のようになり、一方、Guava Collection UtilsとプレーンJava 7

List<A> myList = ... 
Map<A, B> mappings = Maps.uniqueIndex(myList, new Function<A, B>() { 
    @Override 
    public CustomerFinance apply(final A input) { 
     return input.getB(); 
    } 
}); 

List<A> myList = ... 
Map<A, B> mappings = new HashMap<>(myList.size()); 
for (A a : myList) { 
    mappings.put(a.getB(), a); 
} 
オブジェクトから取得した一意のインデックスを持つマップにオブジェクトのリストを置く例えば

はグァバを使用して、このようになります

GuavaのマッピングにはLOCが5つあります(@Override行は数えません)。プレーンJavaのLOCは4つです。

なぜここでグアバのユーティリティを使うべきですか?最初にUtilを作成するインセンティブは何ですか?私はグアバが私に提供するいくつかの付加的な利益を見逃していますか?

+1

Java 8は2年以上にわたって使い果たされており、1行でタスクを実行できます。なぜあなたはJava 7を気にしますか? – Bohemian

+1

私は真剣にしていませんし、後でもっと早くアップグレードしたいと思います。残念ながら、現在取り組んでいるプロジェクトに関わる重要なステークホルダーは、私は反対しています。 –

+1

あなたのJava 7は、Guavaコードの不完全な "翻訳"であるため、短くて済みます。 Guavasの結果のMapは不変であり、値の1つとして 'null'を許可しません。あなたのコードはそれを完全に無視します。 – Tom

答えて

3

グアバが私に提供する追加のメリットがありません。

はい、あります。

あなたの変換されたコードのミスグアバのいくつかの機能(JavaDoc of Maps#uniqueIndex)があります。キーの値について

  • nullが禁止されている(#)
  • nullが禁止されている(キー機能はnullを返すべきではありません
  • 重複するキーは禁止されています(既存のキーを予期せず上書きすることはできません)。
  • 結果のマップはです。テーブル

これらのチェックをすべて行う場合、コードはGuavasバージョンより長くする必要があります。

(#)あなたの値オブジェクトに#getB()と電話したので、翻訳されたバージョンは現在nullを禁止しています。これにより、GuavaのようなNullPointerExceptionが発生します。 mappings.put(generateArtificalKey(), a);のような別の場所からキーを取得する場合、nullはJava 7バージョンで問題ありません。


もう1つの利点は、キー機能のクリーンなコードです。それは簡単に自分のクラスに移動して再利用することができます。その例は、データベースエンティティのIDを抽出してマップを作成する関数です。しかし、これは翻訳されたコード(forループ)が抽出され、他のケースで使用される可能性があるため、事実よりも意見が多いです。

+2

実際には、 'null'に関するあなたの声明は正しくありません:' a.getB() 'が' null'を返すなら、バニラバージョンはNPEを投げません。 –

+0

@StefanHaberlあなたのバージョンはNPEを投げます。なぜなら 'a'が' null'なら 'a.getB()'は動作しないからです。あなたが 'a'で何かを呼び出してキーとして他の何かを使用しないならば、バニラバージョンはNPEを投げません。しかし、あなたのバージョンを参考にしました。だから私はその点を下に移動した(私は最初にそれを持っていた)。私は私の答えが少しはっきりしていることを願っています。 – Tom

+1

もちろん、 'a!= null'と' a.getB()== null'の場合、バニラバージョンは動作しますが、GuavaバージョンはNPEを投げます:D –

2

はい、LOCの点で大きな利益はないと主張するかもしれません。しかし、グアバスタイルはfunctionalです。

変換関数を渡して使用/再利用することができます。

Function<A,B> map = new Function<A, B>() { 
@Override 
public CustomerFinance apply(final A input) { 
    return input.getB(); 
} 

これで地図を渡して別の場所で再利用することができます。

Map<A, B> mappings = Maps.uniqueIndex(myList,map); 
Map<C, D> mappings2 = Maps.uniqueIndex(myList,map); 

しかし、その後、再びは、Guavaは、宣言型スタイルのために最高の体験を与えないのJava 1.6構築物に限定されています。

良いニュースは、あなたは、Java 1.8に移動した場合、

Map<A, B> mappings = Maps.uniqueIndex(myList, input-> input.getB()); 

または

、あなたは初日からラムダを使用して起動することができ、そして、あなたのコードは次のようになりますので、グアバで Functionは、 functional interfaceであるということです
Map<A, B> mappings = Maps.uniqueIndex(myList, A::getB); 
+0

私はラムダをJava 8で使うことができることを知っています。しかし、現在のプロジェクトではJava 7で動かなくなっています。私が機能を共有したり再利用しなかった場合、基本的にそれは味わいの問題(または単によりファッショナブルなアプローチ)であると言いますか? –

+0

@StefanHaberl私は「おしゃれな」と読むことができる答えがあるとは思わない。利点と簡潔さを示すためにいくつかの例を示しました。 –

+0

合意。したがって、私の機能を分かち合い始めると、簡潔さの利点が得られます。私はそうではありません。 Java 8へのアップグレードは(残念ながら)オプションではありません。だから利点はありません。 –

1

私は8より古いJavaのバージョンでプログラムを作成するときに、通常はエンティティとして複数形で名前付きの関連ユーティリティクラスを作成し、すべてのユーティリティメソッドを追加します。こうして、私はエンティティをきれいに保ち、大規模なユーティリティメソッドパネルにアクセスできます。私は体系的にユーティリティクラスを作成するのではなく、ノイズを減らすために必要なときにのみ作成します。

public class MyEntity { 
    private String text; 
    public String getText() { return text; } 
    public void setText (int text) { this.text = text; } 
} 

public final class MyEntities { 
    private MyEntities() {} 

    private enum MyEntityToString implements Function<MyEntity,String> { 
    TEXT_GETTER { 
     @Override public String apply(MyEntity input) { return input.getText(); } 
    }; 
    } 
    public static Function<MyEntity,String> textGetter() { return MyEntityToString.TEXT_GETTER; } 
} 

そして、必要に応じて方法MyEntities.textGetter()を使用するのと同じくらい簡単になります。一度しか使用しないなら、LOCの点では失われますが、何回か使用すると、あなたはただ勝ちます。また、あなたがバグを抱えている場合は、一度だけ修正する必要があります。

+0

私は全く同意します。ドライ。私は正確なコードフラグメントを2回必要とするときに、まったく同じことをやっています(しかし、主に述語を使って)。しかし、たいていの場合、たった1つのユースケースに固有のコードがあります。そして、私はそのロジックを別の関数に外部化したくありません.IMHOは読みにくいです(Java 7に固執したとき) –

+1

1つのユースケースに固有のものなら、それを使っているクラスの別の場所。まだ読むのは簡単です。さらに多くのユースケースが表示されたら、それをユーティリティクラスに移動します。 –

関連する問題