com.google.common.collect.Multimap类的使用及代码示例

x33g5p2x  于2022-01-24 转载在 其他  
字(17.5k)|赞(0)|评价(0)|浏览(1030)

本文整理了Java中com.google.common.collect.Multimap类的一些代码示例,展示了Multimap类的具体用法。这些代码示例主要来源于Github/Stackoverflow/Maven等平台,是从一些精选项目中提取出来的代码,具有较强的参考意义,能在一定程度帮忙到你。Multimap类的具体详情如下:
包路径:com.google.common.collect.Multimap
类名称:Multimap

Multimap介绍

[英]A collection that maps keys to values, similar to Map, but in which each key may be associated with multiple values. You can visualize the contents of a multimap either as a map from keys to nonempty collections of values:

  • a → 1, 2

  • b → 3
    ... or as a single "flattened" collection of key-value pairs:

  • a → 1

  • a → 2

  • b → 3

Important: although the first interpretation resembles how most multimaps are implemented, the design of the Multimap API is based on the second form. So, using the multimap shown above as an example, the #size is 3, not 2, and the #values collection is [1, 2, 3], not [[1, 2], [3]]. For those times when the first style is more useful, use the multimap's #asMap view (or create a Map> in the first place).

Example

The following code:

ListMultimap multimap = ArrayListMultimap.create();for (String firstName : multimap.keySet())  
List lastNames = multimap.get(firstName); 
out.println(firstName + ": " + lastNames); 
} 
}

... produces output such as:

Zachary: [Taylor]

Views

Much of the power of the multimap API comes from the view collections it provides. These always reflect the latest state of the multimap itself. When they support modification, the changes are write-through (they automatically update the backing multimap). These view collections are:

  • #asMap, mentioned above
  • #keys, #keySet, #values, #entries, which are similar to the corresponding view collections of Map
  • and, notably, even the collection returned by #get is an active view of the values corresponding to key

The collections returned by the #replaceValues and #removeAll methods, which contain values that have just been removed from the multimap, are naturally not views.

Subinterfaces

Instead of using the Multimap interface directly, prefer the subinterfaces ListMultimap and SetMultimap. These take their names from the fact that the collections they return from get behave like (and, of course, implement) List and Set, respectively.

For example, the "presidents" code snippet above used a ListMultimap; if it had used a SetMultimap instead, two presidents would have vanished, and last names might or might not appear in chronological order.

Warning: instances of type Multimap may not implement Object#equals in the way you expect. Multimaps containing the same key-value pairs, even in the same order, may or may not be equal and may or may not have the same hashCode. The recommended subinterfaces provide much stronger guarantees.

Comparison to a map of collections

Multimaps are commonly used in places where a Map> would otherwise have appeared. The differences include:

  • There is no need to populate an empty collection before adding an entry with #put.
  • get never returns null, only an empty collection.
  • A key is contained in the multimap if and only if it maps to at least one value. Any operation that causes a key to have zero associated values has the effect of removing that key from the multimap.
  • The total entry count is available as #size.
  • Many complex operations become easier; for example, Collections.min(multimap.values()) finds the smallest value across all keys.

Implementations

As always, prefer the immutable implementations, ImmutableListMultimap and ImmutableSetMultimap. General-purpose mutable implementations are listed above under "All Known Implementing Classes". You can also create a custom multimap, backed by any Mapand Collection types, using the Multimaps#newMultimapfamily of methods. Finally, another popular way to obtain a multimap is using Multimaps#index. See the Multimaps class for these and other static utilities related to multimaps.

Other Notes

As with Map, the behavior of a Multimap is not specified if key objects already present in the multimap change in a manner that affects equals comparisons. Use caution if mutable objects are used as keys in a Multimap.

All methods that modify the multimap are optional. The view collections returned by the multimap may or may not be modifiable. Any modification method that is not supported will throw UnsupportedOperationException.

See the Guava User Guide article on Multimap.
[中]一种将键映射到值的集合,类似于映射,但其中每个键可能与多个值关联。可以将多重映射的内容可视化为从键到非空值集合的映射:
*a→ 1, 2
*b→ 3.
... 或者作为键值对的单个“扁平”集合:
*a→ 1.
*a→ 2.
*b→ 3.
重要提示:尽管第一种解释类似于大多数多重映射的实现方式,但多重映射API的设计基于第二种形式。因此,以上面显示的多重映射为例,#size是3,而不是2,#values集合是[1,2,3],而不是[1,2],[3]。对于第一种样式更有用的情况,请使用多重贴图的#asMap视图(或首先创建一个贴图>)。
####范例
以下代码:

ListMultimap multimap = ArrayListMultimap.create();for (String firstName : multimap.keySet())  
List lastNames = multimap.get(firstName); 
out.println(firstName + ": " + lastNames); 
} 
}

... 产生如下输出:

Zachary: [Taylor]

####观点
multimap API的大部分功能来自它提供的视图集合。这些始终反映多重贴图本身的最新状态。当它们支持修改时,更改将被写入(它们会自动更新备份多重映射)。这些视图集合包括:
*#asMap,如上所述
*#键、#键集、#值、#项,它们类似于地图的相应视图集合
*而且,值得注意的是,即使是#get返回的集合也是与key对应的值的活动视图
#replaceValues和#removeAll方法返回的集合(包含刚从multimap中删除的值)自然不是视图。
####子接口
与其直接使用Multimap接口,不如选择子接口ListMultimap和SetMultimap。它们的名称来源于这样一个事实:它们从get返回的集合的行为分别类似于(当然还有,实现)List和Set。
例如,上面的“总统”代码片段使用了ListMultimap;如果改用SetMultimap,两位总统就会消失,姓氏可能会也可能不会按时间顺序出现。
警告:Multimap类型的实例可能无法按预期的方式实现Object#equals。包含相同键值对的多重映射,即使顺序相同,也可能相等,也可能不相等,并且可能具有或不具有相同的哈希代码。推荐的子接口提供了更强的保证。
####与藏品地图的比较
多重地图通常用于地图>出现的地方。区别包括:
*在添加带有#put的条目之前,无需填充空集合。
*get从不返回null,只返回空集合。
*当且仅当键映射到至少一个值时,它才包含在多重映射中。任何导致键的关联值为零的操作都会从多重映射中删除该键。
*总输入计数以#大小的形式提供。
*许多复杂的操作变得更容易;例如,集合。min(multimap.values())查找所有键的最小值。
####实现
和往常一样,我们更喜欢不可变的实现,ImmutableListMultimap和ImmutableSetMultimap。通用可变实现列在上面的“所有已知实现类”下。您还可以使用Multimaps#newmultimaps方法族创建一个自定义multimap,该multimap由任何映射和集合类型支持。最后,获取多重映射的另一种流行方法是使用多重映射索引。有关这些和其他与多重贴图相关的静态实用程序,请参见多重贴图类。
####其他注释
与Map一样,如果Multimap中已存在的关键对象的更改方式会影响equals比较,则不会指定Multimap的行为。如果可变对象用作多重贴图中的关键点,请小心。
所有修改多重贴图的方法都是可选的。multimap返回的视图集合可以修改,也可以不修改。任何不受支持的修改方法都将引发UnsupportedOperationException。
请参阅关于Multimap的Guava用户指南文章。

代码示例

代码示例来源:origin: google/guava

public void testBuilderPutAllMultimap() {
 Multimap<String, Integer> toPut = LinkedListMultimap.create();
 toPut.put("foo", 1);
 toPut.put("bar", 4);
 toPut.put("foo", 2);
 toPut.put("foo", 3);
 Multimap<String, Integer> moreToPut = LinkedListMultimap.create();
 moreToPut.put("foo", 6);
 moreToPut.put("bar", 5);
 moreToPut.put("foo", 7);
 ImmutableSetMultimap.Builder<String, Integer> builder = ImmutableSetMultimap.builder();
 builder.putAll(toPut);
 builder.putAll(moreToPut);
 Multimap<String, Integer> multimap = builder.build();
 assertEquals(ImmutableSet.of(1, 2, 3, 6, 7), multimap.get("foo"));
 assertEquals(ImmutableSet.of(4, 5), multimap.get("bar"));
 assertEquals(7, multimap.size());
}

代码示例来源:origin: google/error-prone

private static ImmutableList<Fix> buildValidReplacements(
  Multimap<Integer, JCVariableDecl> potentialReplacements,
  Function<JCVariableDecl, Fix> replacementFunction) {
 if (potentialReplacements.isEmpty()) {
  return ImmutableList.of();
 }
 // Take all of the potential edit-distance replacements with the same minimum distance,
 // then suggest them as individual fixes.
 return potentialReplacements.get(Collections.min(potentialReplacements.keySet())).stream()
   .map(replacementFunction)
   .collect(toImmutableList());
}

代码示例来源:origin: google/guava

@GwtIncompatible // SerializableTester
public void testSerialization() {
 Multimap<String, Integer> multimap = createMultimap();
 SerializableTester.reserializeAndAssert(multimap);
 assertEquals(multimap.size(), SerializableTester.reserialize(multimap).size());
 SerializableTester.reserializeAndAssert(multimap.get("foo"));
 LenientSerializableTester.reserializeAndAssertLenient(multimap.keySet());
 LenientSerializableTester.reserializeAndAssertLenient(multimap.keys());
 SerializableTester.reserializeAndAssert(multimap.asMap());
 Collection<Integer> valuesCopy = SerializableTester.reserialize(multimap.values());
 assertEquals(HashMultiset.create(multimap.values()), HashMultiset.create(valuesCopy));
}

代码示例来源:origin: google/guava

public void testContainsKeysFromKeySet() {
 for (K k : multimap().keySet()) {
  assertTrue(multimap().containsKey(k));
 }
}

代码示例来源:origin: google/guava

@Override
protected Iterator<String> newTargetIterator() {
 multimap = LinkedHashMultimap.create();
 multimap.putAll("foo", asList(2, 3));
 multimap.putAll("bar", asList(4, 5));
 multimap.putAll("foo", asList(6));
 multimap.putAll("baz", asList(7, 8));
 multimap.putAll("dog", asList(9));
 multimap.putAll("bar", asList(10, 11));
 multimap.putAll("cat", asList(12, 13, 14));
 return multimap.keySet().iterator();
}

代码示例来源:origin: jclouds/legacy-jclouds

@Test
public void testParseQueryWithKeysThatRequireDecoding() {
 Multimap<String, String> parsedMap = queryParser().apply("network%5B0%5D.id=23&network%5B0%5D.address=192.168.0.1");
 assertEquals(parsedMap.get("network[0].id"), ImmutableSet.of("23"));
 assertEquals(parsedMap.get("network[0].address"), ImmutableSet.of("192.168.0.1"));
}

代码示例来源:origin: prestodb/presto

@Test
public void testScheduleLocal()
{
  Split split = new Split(CONNECTOR_ID, TestingTransactionHandle.create(), new TestSplitLocal());
  Set<Split> splits = ImmutableSet.of(split);
  Map.Entry<Node, Split> assignment = Iterables.getOnlyElement(nodeSelector.computeAssignments(splits, ImmutableList.copyOf(taskMap.values())).getAssignments().entries());
  assertEquals(assignment.getKey().getHostAndPort(), split.getAddresses().get(0));
  assertEquals(assignment.getValue(), split);
}

代码示例来源:origin: prestodb/presto

Multimap<Node, Split> assignments = nodeSelector.computeAssignments(nonRackLocalSplits, ImmutableList.copyOf(taskMap.values())).getAssignments();
MockRemoteTaskFactory remoteTaskFactory = new MockRemoteTaskFactory(remoteTaskExecutor, remoteTaskScheduledExecutor);
int task = 0;
for (Node node : assignments.keySet()) {
  TaskId taskId = new TaskId("test", 1, task);
  task++;
  MockRemoteTaskFactory.MockRemoteTask remoteTask = remoteTaskFactory.createTableScanTask(taskId, node, ImmutableList.copyOf(assignments.get(node)), nodeTaskMap.createPartitionedSplitCountTracker(node, taskId));
  remoteTask.startSplits(25);
  nodeTaskMap.addTask(node, remoteTask);
nonRackLocalSplits = Sets.difference(nonRackLocalSplits, new HashSet<>(assignments.values()));
assignments = nodeSelector.computeAssignments(nonRackLocalSplits, ImmutableList.copyOf(taskMap.values())).getAssignments();
for (Node node : assignments.keySet()) {
  RemoteTask remoteTask = taskMap.get(node);
  remoteTask.addSplits(ImmutableMultimap.<PlanNodeId, Split>builder()
      .putAll(new PlanNodeId("sourceId"), assignments.get(node))
      .build());
nonRackLocalSplits = Sets.difference(nonRackLocalSplits, new HashSet<>(assignments.values()));
for (Node node : assignments.keySet()) {
  RemoteTask remoteTask = taskMap.get(node);
  remoteTask.addSplits(ImmutableMultimap.<PlanNodeId, Split>builder()
      .putAll(new PlanNodeId("sourceId"), assignments.get(node))
      .build());
Set<Split> unassigned = Sets.difference(rackLocalSplits.build(), new HashSet<>(assignments.values()));
for (Node node : assignments.keySet()) {

代码示例来源:origin: prestodb/presto

@Test
public void testMaxSplitsPerNodePerTask()
  nodeManager.addNode(CONNECTOR_ID, newNode);
  ImmutableList.Builder<Split> initialSplits = ImmutableList.builder();
  for (int i = 0; i < 20; i++) {
    initialSplits.add(new Split(CONNECTOR_ID, transactionHandle, new TestSplitRemote()));
    splits.add(new Split(CONNECTOR_ID, transactionHandle, new TestSplitRemote()));
  Multimap<Node, Split> assignments = nodeSelector.computeAssignments(splits, ImmutableList.copyOf(taskMap.values())).getAssignments();
  assertEquals(assignments.keySet().size(), 3); // Splits should be scheduled on the other three nodes
  assertFalse(assignments.keySet().contains(newNode)); // No splits scheduled on the maxed out node
  assertEquals(nodeTaskMap.getPartitionedSplitsOnNode(newNode), 0);

代码示例来源:origin: apache/incubator-druid

@Override
public List<TaskLock> getLocks(final String taskid)
{
 giant.lock();
 try {
  return ImmutableList.copyOf(taskLocks.get(taskid));
 }
 finally {
  giant.unlock();
 }
}

代码示例来源:origin: prestodb/presto

@Test
public void testBasicAssignment()
{
  // One split for each node
  Set<Split> splits = new HashSet<>();
  for (int i = 0; i < 3; i++) {
    splits.add(new Split(CONNECTOR_ID, TestingTransactionHandle.create(), new TestSplitRemote()));
  }
  Multimap<Node, Split> assignments = nodeSelector.computeAssignments(splits, ImmutableList.copyOf(taskMap.values())).getAssignments();
  assertEquals(assignments.entries().size(), 3);
  for (Node node : nodeManager.getActiveConnectorNodes(CONNECTOR_ID)) {
    assertTrue(assignments.keySet().contains(node));
  }
}

代码示例来源:origin: google/guava

public void testFlatteningToImmutableListMultimap() {
 Collector<String, ?, ImmutableListMultimap<Character, Character>> collector =
   ImmutableListMultimap.flatteningToImmutableListMultimap(
     str -> str.charAt(0), str -> str.substring(1).chars().mapToObj(c -> (char) c));
 BiPredicate<Multimap<?, ?>, Multimap<?, ?>> equivalence =
   Equivalence.equals()
     .onResultOf((Multimap<?, ?> mm) -> ImmutableList.copyOf(mm.asMap().entrySet()))
     .and(Equivalence.equals());
 ImmutableListMultimap<Character, Character> empty = ImmutableListMultimap.of();
 ImmutableListMultimap<Character, Character> filled =
   ImmutableListMultimap.<Character, Character>builder()
     .putAll('b', Arrays.asList('a', 'n', 'a', 'n', 'a'))
     .putAll('a', Arrays.asList('p', 'p', 'l', 'e'))
     .putAll('c', Arrays.asList('a', 'r', 'r', 'o', 't'))
     .putAll('a', Arrays.asList('s', 'p', 'a', 'r', 'a', 'g', 'u', 's'))
     .putAll('c', Arrays.asList('h', 'e', 'r', 'r', 'y'))
     .build();
 CollectorTester.of(collector, equivalence)
   .expectCollects(empty)
   .expectCollects(filled, "banana", "apple", "carrot", "asparagus", "cherry");
}

代码示例来源:origin: google/guava

@MapFeature.Require(SUPPORTS_PUT)
public void testPutEmpty() {
 int size = getNumElements();
 assertGet(k3(), ImmutableList.<V>of());
 assertTrue(multimap().put(k3(), v3()));
 assertGet(k3(), v3());
 assertEquals(size + 1, multimap().size());
}

代码示例来源:origin: prestodb/presto

@Test
public void testApproxPercentile()
  Multimap<String, Double> totalPriceByStatus = ArrayListMultimap.create();
  for (MaterializedRow row : raw.getMaterializedRows()) {
    orderKeyByStatus.put((String) row.getField(0), ((Number) row.getField(1)).longValue());
    totalPriceByStatus.put((String) row.getField(0), (Double) row.getField(2));
    Double totalPriceWeighted = (Double) row.getField(4);
    List<Long> orderKeys = Ordering.natural().sortedCopy(orderKeyByStatus.get(status));
    List<Double> totalPrices = Ordering.natural().sortedCopy(totalPriceByStatus.get(status));
    assertTrue(orderKey >= orderKeys.get((int) (0.49 * orderKeys.size())));
    assertTrue(orderKey <= orderKeys.get((int) (0.51 * orderKeys.size())));
    assertTrue(orderKeyWeighted >= orderKeys.get((int) (0.49 * orderKeys.size())));
    assertTrue(orderKeyWeighted <= orderKeys.get((int) (0.51 * orderKeys.size())));

代码示例来源:origin: linkedin/flashback

@Test
public void testGetCharset()
  throws URISyntaxException {
 Multimap<String, String> headers = LinkedHashMultimap.create();
 headers.put(HttpHeaders.CONTENT_TYPE, "text/html; charset=iso-8859-9");
 RecordedHttpRequest recordedHttpRequest = new RecordedHttpRequest("GET", new URI("google.com"), headers, null);
 Assert.assertEquals(recordedHttpRequest.getCharset(), Charset.forName("iso-8859-9").toString());
}

代码示例来源:origin: prestodb/presto

return ImmutableSet.of();
checkArgument(stateMachine.getFragment().getPartitionedSources().containsAll(splits.keySet()), "Invalid splits");
ImmutableSet.Builder<RemoteTask> newTasks = ImmutableSet.builder();
Collection<RemoteTask> tasks = this.tasks.get(node);
RemoteTask task;
  task.addSplits(splits);
if (noMoreSplitsNotification.size() > 1) {
for (Entry<PlanNodeId, Lifespan> entry : noMoreSplitsNotification.entries()) {
  task.noMoreSplits(entry.getKey(), entry.getValue());

代码示例来源:origin: google/guava

public void testBuilderPutAllIterable() {
 ImmutableSetMultimap.Builder<String, Integer> builder = ImmutableSetMultimap.builder();
 builder.putAll("foo", Arrays.asList(1, 2, 3));
 builder.putAll("bar", Arrays.asList(4, 5));
 builder.putAll("foo", Arrays.asList(6, 7));
 Multimap<String, Integer> multimap = builder.build();
 assertEquals(ImmutableSet.of(1, 2, 3, 6, 7), multimap.get("foo"));
 assertEquals(ImmutableSet.of(4, 5), multimap.get("bar"));
 assertEquals(7, multimap.size());
}

代码示例来源:origin: apache/incubator-gobblin

@Test
public void testHashCode() throws Exception {
 CopyableDataset copyableDataset = new TestCopyableDataset();
 Path target = new Path("/target");
 CopyableDatasetMetadata metadata = new CopyableDatasetMetadata(copyableDataset);
 String serialized = metadata.serialize();
 CopyableDatasetMetadata deserialized = CopyableDatasetMetadata.deserialize(serialized);
 CopyableDatasetMetadata deserialized2 = CopyableDatasetMetadata.deserialize(serialized);
 Multimap<CopyableDatasetMetadata, WorkUnitState> datasetRoots = ArrayListMultimap.create();
 datasetRoots.put(deserialized, new WorkUnitState());
 datasetRoots.put(deserialized2, new WorkUnitState());
 Assert.assertEquals(datasetRoots.keySet().size(), 1);
}

代码示例来源:origin: google/guava

@Override
public Collection<Entry<String, Integer>> create(Object... elements) {
 Multimap<String, Integer> multimap = createMultimap();
 for (Object element : elements) {
  @SuppressWarnings("unchecked")
  Entry<String, Integer> entry = (Entry<String, Integer>) element;
  multimap.put(entry.getKey(), entry.getValue());
 }
 return multimap.entries();
}

代码示例来源:origin: linkedin/flashback

@Test
 public void testBodyMatchForDifferentRequestTypes() {
  RecordedHttpBody incomingHttpBody = new RecordedStringHttpBody("------wxyz1234abcd5e\nContent-Disposition: form-data; name=\"org\" \nMMM\n------wxyz1234abcd5e");
  Multimap<String, String> headers1 = LinkedHashMultimap.create();
  headers1.put(HttpHeaders.CONTENT_TYPE, "multipart/form-data; boundary=wxyz1234abcd5e");
  Multimap<String, String> headers2 = LinkedHashMultimap.create();

  RecordedHttpRequest recordedHttpRequest1 = new RecordedHttpRequest("POST", null, headers1, incomingHttpBody);
  RecordedHttpRequest recordedHttpRequest2 = new RecordedHttpRequest("GET", null, headers2, null);
  MatchRule matchRule = new MatchBodyWithAnyBoundary();
  Assert.assertFalse(matchRule.test(recordedHttpRequest1, recordedHttpRequest2));
 }
}

相关文章