为什么 Google Guava 提供存在等效构造函数的静态方法?
Why does Google Guava offer static methods where equivalent constructors exist?
我注意到 Google Guava Sets
class offers methods such as newHashSet
taking an Iterable
or Iterator
. The HashSet
class 与 Java 捆绑在一起已经提供了一个采用 Collection
的构造函数,从而提供了类似的行为。
所以我很好奇……Guava Sets中这些特定的静态方法有什么优势?仅仅是因为 Iterable
或 Iterator
对象 而不是 也是 Collection
吗?或者 Guava 团队是否有其他目的而费心包含这些方法?
根据 Google Guava 文档,CollectionUtilitiesExplained:
Whenever possible, Guava prefers to provide utilities accepting an Iterable
rather than a Collection
. Here at Google, it's not out of the ordinary to encounter a "collection" that isn't actually stored in main memory, but is being gathered from a database, or from another data center, and can't support operations like size()
without actually grabbing all of the elements.
As a result, many of the operations you might expect to see supported for all collections can be found in Iterables
. Additionally, most Iterables
methods have a corresponding version in Iterators
that accepts the raw iterator.
The overwhelming majority of operations in the Iterables
class are lazy: they only advance the backing iteration when absolutely necessary. Methods that themselves return Iterables
return lazily computed views, rather than explicitly constructing a collection in memory.
Iterable
接口在 Java 1.5 中引入,是 Collection
接口
的基础接口
HashSet
构造函数早于此修改,我认为为了兼容性,他们将其保留为 Java 1.5
另一方面,Guava 不受此更改的限制,为方便起见,提供了采用 Iterator
.
的构造函数
默认情况下 Iterable
构造函数尝试将 Iterable
转换为 Collection
,如果不可能,则继续提取其 Iterator
并调用 Iterator
构造函数。
在我看来,这为图书馆用户提供了更好的灵活性。
存在 Sets
实用程序 class 的另一个原因是 Java 1.5 和 1.6 在调用泛型构造函数时需要手写。
这个特殊问题在 1.7 中通过引入菱形运算符得到解决。
举例说明。
1.7 之前
ArrayList<String> myList = ...
// See generic parameter repeated
HashSet<String> mySet = new HashSet<String>( myList );
// No such issue for statics
HashSet<String> myGuavaSet = Sets.newHashSet( myList );
1.7 之后
ArrayList<String> myList = ...
// Notice diamond
HashSet<String> mySet = new HashSet<>( myList );
// Really no reason now to use Guava for HashSet construction in most cases
我注意到 Google Guava Sets
class offers methods such as newHashSet
taking an Iterable
or Iterator
. The HashSet
class 与 Java 捆绑在一起已经提供了一个采用 Collection
的构造函数,从而提供了类似的行为。
所以我很好奇……Guava Sets中这些特定的静态方法有什么优势?仅仅是因为 Iterable
或 Iterator
对象 而不是 也是 Collection
吗?或者 Guava 团队是否有其他目的而费心包含这些方法?
根据 Google Guava 文档,CollectionUtilitiesExplained:
Whenever possible, Guava prefers to provide utilities accepting an
Iterable
rather than aCollection
. Here at Google, it's not out of the ordinary to encounter a "collection" that isn't actually stored in main memory, but is being gathered from a database, or from another data center, and can't support operations likesize()
without actually grabbing all of the elements.As a result, many of the operations you might expect to see supported for all collections can be found in
Iterables
. Additionally, mostIterables
methods have a corresponding version inIterators
that accepts the raw iterator.The overwhelming majority of operations in the
Iterables
class are lazy: they only advance the backing iteration when absolutely necessary. Methods that themselves returnIterables
return lazily computed views, rather than explicitly constructing a collection in memory.
Iterable
接口在 Java 1.5 中引入,是 Collection
接口
HashSet
构造函数早于此修改,我认为为了兼容性,他们将其保留为 Java 1.5
另一方面,Guava 不受此更改的限制,为方便起见,提供了采用 Iterator
.
默认情况下 Iterable
构造函数尝试将 Iterable
转换为 Collection
,如果不可能,则继续提取其 Iterator
并调用 Iterator
构造函数。
在我看来,这为图书馆用户提供了更好的灵活性。
存在 Sets
实用程序 class 的另一个原因是 Java 1.5 和 1.6 在调用泛型构造函数时需要手写。
这个特殊问题在 1.7 中通过引入菱形运算符得到解决。
举例说明。
1.7 之前
ArrayList<String> myList = ...
// See generic parameter repeated
HashSet<String> mySet = new HashSet<String>( myList );
// No such issue for statics
HashSet<String> myGuavaSet = Sets.newHashSet( myList );
1.7 之后
ArrayList<String> myList = ...
// Notice diamond
HashSet<String> mySet = new HashSet<>( myList );
// Really no reason now to use Guava for HashSet construction in most cases