Guava库提供了丰富的集合类API,这些API扩展了Java标准库中的集合功能,提供了更多的灵活性和便利性。
在日常开发中,集合类是我们日常编程不可或缺的一部分。Java标准库为我们提供了一套基本的集合类,但在实际项目中,我们往往需要更加灵活和强大的集合功能。这时,Google的Guava库便成为了我们的得力助手。Guava库扩展了Java的集合类,提供了一系列高效、实用且易于使用的集合API。在本文中,我们将深入探索Guava库中常用的集合类API,并了解它们如何提升我们的开发效率。
首先,我们要介绍的是Guava提供的不可变集合。在编程中,有时我们需要创建一些一旦初始化就不会再更改的集合。这些集合被称为不可变集合。Guava为我们提供了ImmutableList、ImmutableSet和ImmutableMap等不可变集合的实现。这些集合在创建时确定了内容,并且保证了之后无法修改。这种不可变性带来了诸多好处,比如线程安全、减少错误和提高代码可读性。当你需要一个不会变动的集合时,Guava的不可变集合将是你的最佳选择。
其他API敬请期待后续文章
一个不可变的列表实现,提供了与Java List接口类似的方法,但保证了列表内容不可更改。
一个不可变的集合实现,与Java Set接口类似,但不允许添加或删除元素。
一个不可变的映射实现,类似于Java的Map接口,但键值对是固定的,无法修改。
这些不可变集合在创建时确定内容,之后不可更改,有助于编写线程安全的代码。
在pom.xml中添加如下依赖:
<dependency>
<groupId>com.google.guavagroupId>
<artifactId>guavaartifactId>
<version>31.0.1-jreversion>
dependency>
然后,在你的Java代码中使用这些不可变集合:
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableMap;
public class GuavaImmutableCollectionsExample {
public static void main(String[] args) {
// 创建一个ImmutableList
ImmutableList<String> immutableList = ImmutableList.of("Apple", "Banana", "Cherry");
System.out.println("ImmutableList: " + immutableList);
// 尝试修改ImmutableList(这将导致编译时错误)
// immutableList.add("Date"); // 这行代码将无法编译
// 创建一个ImmutableSet
ImmutableSet<Integer> immutableSet = ImmutableSet.of(1, 2, 3, 4, 5);
System.out.println("ImmutableSet: " + immutableSet);
// 尝试修改ImmutableSet(这也将导致编译时错误)
// immutableSet.add(6); // 这行代码也无法编译
// 创建一个ImmutableMap
ImmutableMap<String, Integer> immutableMap = ImmutableMap.of("One", 1, "Two", 2, "Three", 3);
System.out.println("ImmutableMap: " + immutableMap);
// 尝试修改ImmutableMap(这同样会导致编译时错误)
// immutableMap.put("Four", 4); // 这行代码也无法编译
// 访问ImmutableMap中的元素
Integer value = immutableMap.get("Two");
System.out.println("Value associated with 'Two': " + value);
}
}
在上面的代码中,我们展示了如何使用Guava的不可变集合类来创建列表、集合和映射,并尝试(不成功地)修改它们。由于这些集合是不可变的,任何尝试修改它们的操作都会在编译时失败。这对于需要确保数据一致性和线程安全的场景非常有用。
ImmutableTable、ImmutableEnumSet 和 ImmutableEnumMap 在Guava并没有直接提供这些具体的实现。在实际使用中,你应该根据具体的需求选择合适的不可变集合类型,并结合 Java 标准库和 Guava
提供的工具来创建和操作这些集合
这两个接口分别表示不可变的排序集合和排序映射。它们提供了根据元素的自然顺序或指定的比较器排序的功能。例如:
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.Ordering;
import java.util.Comparator;
public class GuavaImmutableSortedCollectionsExample {
public static void main(String[] args) {
// 创建一个根据自然顺序排序的ImmutableSortedSet
ImmutableSortedSet<Integer> sortedSet = ImmutableSortedSet.copyOf(Ordering.natural(), 10, 5, 15, 20);
System.out.println("ImmutableSortedSet (natural order): " + sortedSet);
// 创建一个根据自定义比较器排序的ImmutableSortedSet
Comparator<String> stringComparator = Comparator.comparing(String::length);
ImmutableSortedSet<String> sortedSetCustomOrder = ImmutableSortedSet.copyOf(stringComparator, "apple", "banana", "kiwi", "pear");
System.out.println("ImmutableSortedSet (custom order): " + sortedSetCustomOrder);
// 创建一个根据自然顺序排序键的ImmutableSortedMap
ImmutableSortedMap<Integer, String> sortedMap = ImmutableSortedMap.of(5, "five", 1, "one", 3, "three");
// 注意:上面的of方法会根据键的自然顺序对条目进行排序,但这里我们传入的已经是排序好的键值对
System.out.println("ImmutableSortedMap (natural order): " + sortedMap);
// 创建一个根据自定义比较器排序键的ImmutableSortedMap
ImmutableSortedMap<String, Integer> sortedMapCustomOrder =
ImmutableSortedMap.orderedBy(stringComparator)
.put("apple", 1)
.put("banana", 2)
.put("kiwi", 3)
.put("pear", 4)
.build();
System.out.println("ImmutableSortedMap (custom order): " + sortedMapCustomOrder);
}
}
这两个接口分别表示不可变的多重集和多重映射。多重集允许元素重复出现,而多重映射则允许一个键映射到多个值。例如:
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Multiset;
import com.google.common.collect.Multimap;
import java.util.Arrays;
public class GuavaImmutableMultiCollectionsExample {
public static void main(String[] args) {
// 创建一个ImmutableMultiset
ImmutableMultiset<String> multiset = ImmutableMultiset.<String>builder()
.addAll(Arrays.asList("apple", "apple", "banana", "orange"))
.addCopies("banana", 2) // 添加额外的"banana"元素
.build();
System.out.println("ImmutableMultiset: " + multiset);
// 展示元素及其出现次数
for (Multiset.Entry<String> entry : multiset.entrySet()) {
System.out.println(entry.getElement() + ": " + entry.getCount());
}
// 创建一个ImmutableMultimap
ImmutableMultimap<String, Integer> multimap = ImmutableMultimap.<String, Integer>builder()
.putAll("fruits", Arrays.asList(1, 2, 3))
.putAll("veggies", Arrays.asList(4, 5))
.put("fruits", 6) // 添加额外的键值对到"fruits"
.build();
System.out.println("ImmutableMultimap: " + multimap);
// 展示键及其对应的值
for (String key : multimap.keySet()) {
System.out.println(key + " => " + multimap.get(key));
}
}
}
在这个示例中,我们展示了如何创建 ImmutableMultiset 和 ImmutableMultimap。ImmutableMultiset 允许元素重复出现,并且我们可以使用 addCopies 方法来添加指定数量的元素。ImmutableMultimap 允许一个键映射到多个值。
输出将类似于以下内容:
ImmutableMultiset: [apple x 2, banana x 3, orange]
apple: 2
banana: 3
orange: 1
ImmutableMultimap: {fruits=[1, 2, 3, 6], veggies=[4, 5]}
fruits => [1, 2, 3, 6]
veggies => [4, 5]
请注意,ImmutableMultiset 和 ImmutableMultimap 都是不可变的,这意味着一旦创建,您就不能向它们添加或删除元素。如果您需要一个可变的版本,可以使用 Multiset 和 Multimap 接口的其他实现,例如 HashMultiset 和 ArrayListMultimap,然后在需要的时候使用 ImmutableMultiset.copyOf(multiset) 或 ImmutableMultimap.copyOf(multimap) 来创建不可变副本。
ImmutableTable 是 Google Guava 库中提供的一种不可变的三维表格数据结构。它类似于 ImmutableMap,但是它可以存储两个键和一个值的映射关系,可以看作是一种特殊的集合。它允许你通过行和列来访问元素。例如:
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Table;
import java.util.Map;
public class GuavaImmutableTableExample {
public static void main(String[] args) {
// 创建一个ImmutableTable
ImmutableTable<String, String, Integer> table = ImmutableTable.<String, String, Integer>builder()
.put("apple", "red", 1)
.put("apple", "green", 2)
.put("banana", "yellow", 3)
.build();
// 输出整个表格
System.out.println("ImmutableTable: " + table);
// 获取某个键对应的行映射
Map<String, Integer> appleRow = table.row("apple");
System.out.println("Apple row: " + appleRow);
// 获取某个列对应的映射
Map<String, Integer> redColumn = table.column("red");
System.out.println("Red column: " + redColumn);
// 获取某个具体的值
Integer valueOfAppleRed = table.get("apple", "red");
System.out.println("Value of apple red: " + valueOfAppleRed);
// 判断是否包含某个键值对
boolean containsAppleGreen = table.contains("apple", "green");
System.out.println("Contains apple green: " + containsAppleGreen);
// 尝试修改(注意:这会失败,因为ImmutableTable是不可变的)
// table.put("apple", "red", 42); // 这行代码会导致编译错误
}
}
请注意,在上面的例子中,ImmutableTable.copyOf 方法实际上并不直接存在于 Guava 库中。相反,你应该使用 Tables.immutableTable 方法,但这个方法接受的是一个已经存在的表格,并返回一个不可变的视图。然而,由于 Guava 没有直接提供一个简单的方法来创建一个全新的不可变表格,通常的做法是先创建一个可变的表格,然后将其转换为一个不可变的视图。
表示不可变的、双向映射的集合。它同时提供了键到值和值到键的映射关系,并且保证了键和值的唯一性。与 ImmutableMap 类似,它也不允许添加、删除或更改映射关系。
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableBiMap.Builder;
public class ImmutableBiMapExample {
public static void main(String[] args) {
// 使用 Builder 创建 ImmutableBiMap
Builder<String, Integer> builder = ImmutableBiMap.builder();
builder.put("one", 1);
builder.put("two", 2);
builder.put("three", 3);
ImmutableBiMap<String, Integer> biMap = builder.build();
// 输出整个双向映射
System.out.println("ImmutableBiMap: " + biMap);
// 通过键获取值
Integer valueOne = biMap.get("one");
System.out.println("Value for 'one': " + valueOne);
// 通过值获取键(这是 BiMap 的特点)
String keyForValueTwo = biMap.inverse().get(2);
System.out.println("Key for value 2: " + keyForValueTwo);
// 尝试修改(注意:这会失败,因为 ImmutableBiMap 是不可变的)
// biMap.put("four", 4); // 这行代码会导致编译错误
// 尝试使用已存在的值作为键进行插入(也会失败,因为值也必须唯一)
// builder.put("four", 2); // 这同样会导致错误,即使你试图在 build() 之后再做
}
}
在上面的示例中,我使用了 ImmutableBiMap.Builder 来构建一个 ImmutableBiMap 实例。这个双向映射允许你通过键来查找值,也可以通过值来查找键(使用 inverse() 方法)。由于 ImmutableBiMap 是不可变的,任何试图修改它的操作(如 put 方法)都会导致编译时错误。
请注意,在构建 ImmutableBiMap 之后,你不能再使用 builder 添加或修改条目,因为 builder 已经在 build() 调用时被消耗掉了。如果你需要另一个不同的 ImmutableBiMap,你必须创建一个新的 Builder 实例。
此外,ImmutableBiMap 保证键和值的唯一性,所以每个键映射到一个唯一的值,每个值也映射到一个唯一的键。这意味着你不能在 ImmutableBiMap 中有重复的键或值。
这些不可变集合的 API 都具有相似的特点,即不允许修改集合内容,提供了线程安全的访问方式,并且在创建时就需要确定集合的元素。这些集合类型在 Guava 库中被广泛使用,可以帮助开发者编写更加健壮和可维护的代码。
需要注意的是,所有 Guava 不可变集合的实现都不接受 null 值。如果需要在不可变集合中使用 null,可以考虑使用 JDK 中的 Collections.unmodifiableXXX 方法。
以上是关于 Google Guava 不可变集合 API 的简要介绍,更多详细信息和用法可以参考 Guava 官方文档。