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 super K, V> 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);
+ }
+
}