diff --git a/core/src/main/java/org/jclouds/util/Maps2.java b/core/src/main/java/org/jclouds/util/Maps2.java index 869f6b644d..c58d853553 100644 --- a/core/src/main/java/org/jclouds/util/Maps2.java +++ b/core/src/main/java/org/jclouds/util/Maps2.java @@ -26,16 +26,17 @@ import static com.google.common.collect.Maps.filterKeys; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import com.google.common.base.Function; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; -import com.google.common.collect.ImmutableMap.Builder; /** - * General utilities used in jclouds code for {@link Map}s. + * General utilities used in jclouds code for {@link Map Maps}. * * @author Adrian Cole */ @@ -120,5 +121,25 @@ public class Maps2 { return toReturn; } } + + /** + * Constructs a map with the given keys where values are generated by the given function. + * Supports duplicate and {@code null} values, but {@code null} keys are not allowed. + * + * @param the type of the keys + * @param the type of the values + * @param keys the keys to be included in the map. Keys must be non-null + * @param valueFunction the function that produces values for the keys + * @return a map containing the keys from the given set with values which are generated from + * the keys + * @see Maps#uniqueIndex(Iterable, Function) + */ + public static Map fromKeys(Set keys, Function valueFunction) { + Map result = Maps.newHashMapWithExpectedSize(keys.size()); + for (K key : keys) { + result.put(checkNotNull(key), valueFunction.apply(key)); + } + return result; + } } diff --git a/core/src/test/java/org/jclouds/util/Maps2Test.java b/core/src/test/java/org/jclouds/util/Maps2Test.java index f3ebc6c236..085d284387 100644 --- a/core/src/test/java/org/jclouds/util/Maps2Test.java +++ b/core/src/test/java/org/jclouds/util/Maps2Test.java @@ -18,7 +18,11 @@ */ package org.jclouds.util; +import static com.google.common.base.Functions.constant; +import static com.google.common.base.Functions.identity; +import static com.google.common.collect.Sets.newHashSet; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; import java.util.Map; @@ -26,6 +30,8 @@ import org.testng.annotations.Test; import com.google.common.base.Function; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; /** * @author Adrian Cole @@ -54,4 +60,30 @@ public class Maps2Test { }), ImmutableMap.of("foo", "bar")); } + public void testFromKeysEmptyKeys() { + assertTrue(Maps2.fromKeys(ImmutableSet.of(), identity()).isEmpty(), + "Expected returned map to be empty"); + } + + @Test(expectedExceptions = { NullPointerException.class }) + public void testFromKeysNullKey() { + Maps2.fromKeys(newHashSet((Object) null), constant("const")); + } + + public void testFromKeys() { + // ImmutableMap doesn't support null values + Map expected = Maps.newHashMap(); + expected.put("foo", "foo"); + expected.put("bar", "foo"); + expected.put("baz", null); + + assertEquals(Maps2.fromKeys(ImmutableSet.of("foo", "bar", "baz"), + new Function() { + @Override + public String apply(String input) { + return (input.equals("baz") ? null : "foo"); + } + }), expected); + } + }