[英]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.