簡體   English   中英

Guava Collection Utils與普通Java 7

[英]Guava Collection Utils vs. plain Java 7

我經常想用Guava的集合utils編寫代碼,並發現自己在看了代碼片段后用純Java 7重寫了代碼,因為它的IMHO變得更簡潔,使用普通的舊Java更容易閱讀。

例如,使用Guava將具有對象唯一索引的對象列表放入地圖中,將看起來像這樣:

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

而在普通Java 7中,它將是:

List<A> myList = ...
Map<A, B> mappings = new HashMap<>(myList.size());
for (A a : myList) {
    mappings.put(a.getB(), a);
}

這是Guava中映射的5個LOC(即使不計算@Override行),而普通Java中則是4個LOC。

為什么要在這里使用Guava utils? 首先創建實用程序的動機是什么? 我是否錯過了番石榴會為我提供的其他好處?

我是否錯過了番石榴會為我提供的其他好處?

是的你是。

Guava中有一些功能,您的翻譯后的代碼會丟失( Maps#uniqueIndex的JavaDoc ):

  • null禁止(#)
  • 鍵的null被禁止(鍵函數對於給定的值不應返回null
  • 禁止重復密鑰(您不能意外覆蓋現有密鑰)
  • 結果圖是不可變的

如果還進行所有這些檢查,那么您的代碼應該比Guavas版本更長。

(#)注意,您的翻譯版本目前也禁止使用null ,因為您在值對象上調用了#getB() 這將導致類似Guava的NullPointerException 如果您可以從其他地方(例如mappings.put(generateArtificalKey(), a);獲取密鑰mappings.put(generateArtificalKey(), a); ,則對於Java 7版本,可以使用null


另一個優點是按鍵功能的代碼更簡潔。 可以輕松地將其移入自己的類並進行重用。 例如,可以使用一個函數提取數據庫實體的ID來創建一個映射。 但這不是事實,因為您的翻譯代碼( for循環)也可以提取出來並用於其他情況,因此,這比事實更有意義。

您可能會說是的,就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構造,它不能提供最佳的聲明式體驗。

好消息是Guava中的Function是一個functional interface ,因此,如果您使用Java 1.8,則可以從第一天開始使用lambda,並且您的代碼將如下所示:

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

要么

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

當我在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,但是如果多次使用,您只會贏。 另外,如果您遇到錯誤,則只需要修復一次即可,而不必查找每種用法都可以在任何地方修復它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM