2015-09-07 53 views
3

我有两个数组。 intstring。如何将该数组转换为映射?在地图中转换两个原始数组。并将结果映射转换为该数组

我的代码。首先,我已经转换INT为包装整数

public static Integer[] toObject(int[] array) { 
     Integer[] result = new Integer[array.length]; 
     for (int i = 0; i < array.length; i++) { 
      result[i] = new Integer(array[i]); 
     } 
     return result; 
    } 

在那之后,我已经转换两个数组为地图

public static <T,V> HashMap<T, V> toHM(T[] array, V[] array2) { 
     HashMap<T,V> h = new LinkedHashMap<>(); 

     for(int i= 0; i < array.length; i++){ 
      h.put(array[i], array2[i]); 
     } 
     return h; 
    } 

这是正确的? 之后,我需要在原始数组中进行转换。这个怎么做 ?

例子:

Map<Integer, String> map = new HashMap<Integer, String>(); 
Integer[] keys = new Integer[map.size()]; 
String[] values = new String[map.size()]; 
int index = 0; 
for (Map.Entry<Integer, String> mapEntry : map.entrySet()) { 
    keys[index] = mapEntry.getKey(); 
    values[index] = mapEntry.getValue(); 
    index++; 
} 

但我需要的方法来实现这一点。这个怎么做 ? 而这还不是全部。我需要在原语中转换结果包装数组。

可能是,你告诉我,如何在你的方法中实现它?

  • 第一:我需要在所有映射方法(hashmap,treemap,linkedhashmap)中转换两个基元数组。
  • 第二:我需要在我的两个原始数组中转换结果hashmap。
+0

您正在使用哪个版本的java? –

+0

我只使用java 8 – Valeriu

+0

然后你不需要将原语转换为包装,你可以直接把它们放在地图上。 –

回答

1

如果我猜测正确的话,你想接收一对阵列的通用方法原始类型并返回一个特定的映射,其键和值与数组的值匹配。

另外,您需要另一种方法接收映射并返回一对基元类型的数组,其元素与映射的条目相匹配。

如果这些假设是正确的,那么你可以尝试这样的事情您的原语:

public static Integer[] box(int[] primitives) { 
    return IntStream.of(primitives).boxed().toArray(Integer[]::new); 
} 

public static Byte[] box(byte[] primitives) { 
    return IntStream.range(0, primitives.length).mapToObj(
     i -> primitives[i]).toArray(Byte[]::new); 
} 

// short, char and boolean left as an exercise 

public static Double[] box(double[] primitives) { 
    return DoubleStream.of(primitives).boxed().toArray(Double[]::new); 
} 

public static Float[] box(float[] primitives) { 
    return IntStream.range(0, primitives.length).mapToObj(
     i -> primitives[i]).toArray(Float[]::new); 
} 

public static Long[] box(long[] primitives) { 
    return LongStream.of(primitives).boxed().toArray(Long[]::new); 
} 

然后,可以按如下方式实现一个通用toMap()方法:

public static <K, V, M extends Map<K, V>> M toMap(
    K[] keys, 
    V[] values, 
    Supplier<M> factory) { 

    return IntStream.range(0, keys.length).boxed().collect(
     Collectors.toMap(i -> keys[i], i -> values[i], (a, b) -> a, factory)); 
} 

通过迭代keysvalues数组,将流收集到地图上,将各个元素对放在地图上,由提供参数。这factory实际上是一个Supplier将被用来创建一个具体的Map实现,即HashMapTreeMapLinkedHashMap

请注意,你可能会失去的元素排序,如果地图上执行不保留插入顺序,比如它发生在HashMap

对于反向操作,你需要一个辅助类,将举行两个数组:

public class Pair<A, B> { 

    public Pair(A a, B b) { 
     this.a = a; 
     this.b = b; 
    } 

    public final A a; 

    public final B b; 
} 

这是一个简单的对持有人。然后,你可以改变一个给定的地图,一对列如下:

public static <K, V, M extends Map<K, V>> Pair<K[], V[]> toArrays(
    M map, 
    IntFunction<K[]> keysFactory, 
    IntFunction<V[]> valuesFactory) { 

    K[] keys = map.keySet().stream().toArray(keysFactory); 
    V[] values = map.values().stream().toArray(valuesFactory); 
    return new Pair<>(keys, values); 
} 

这分别流在给定地图的keySet()values()收集,创建keysvalues阵列。提供了各自为阵列提供工厂角色的IntFunction。这是为了使泛型机制按预期工作,否则你将无法修复数组元素的泛型类型来映射键和值的泛型类型。

Pair类中,不能保存原始数组,因为它是通用的,并且(截至2015年9月)仍不允许使用基本类型作为类型参数。

因此,我们需要几个拆箱方法:

public static int[] unbox(Integer[] wrappers) { 
    return Arrays.stream(wrappers).mapToInt(Integer::intValue).toArray(); 
} 

public static float[] unbox(Float[] wrappers) { 
    float[] result = new float[wrappers.length]; 
    IntStream.range(0, wrappers.length).forEachOrdered(
     i -> result[i] = wrappers[i].floatValue()); 
    return result; 
} 

// Rest of unbox methods left as an exercise 

最后,这里说明了如何这种代码可以使用例如:

String[] keys = { "one", "two", "three" }; 
int[] intValues = { 1, 2, 3 }; 
float[] floatValues = { 1.1f, 2.2f, 3.3f }; 

Integer[] integers = box(intValues); 
Map<String, Integer> map = toMap(keys, integers, HashMap::new); 
System.out.println(map); // {one=1, three=3, two=2} 

Float[] floats = box(floatValues); 
Map<String, Float> map2 = toMap(keys, floats, LinkedHashMap::new); 
System.out.println(map2); // {one=1.1, two=2.2, three=3.3} 

Pair<String[], Integer[]> arrays = toArrays(map, String[]::new, Integer[]::new); 
System.out.println(Arrays.toString(arrays.a)); // [one, three, two] 
int[] unboxedInts = unbox(arrays.b); 
System.out.println(Arrays.toString(unboxedInts)); // [1, 3, 2] 

Pair<String[], Float[]> arrays2 = toArrays(map2, String[]::new, Float[]::new); 
System.out.println(Arrays.toString(arrays2.a)); // [one, two, three] 
float[] unboxedFloats = unbox(arrays2.b); 
System.out.println(Arrays.toString(unboxedFloats)); // [1.1, 2.2, 3.3] 

有用于花车,布尔没有流,短裤,在Java中不使用字节,所以你必须使用一些解决方法。

泛型语法不是很清楚,但它可以让你修复泛型,比如我用键和值做的地图。

最后注意:HashMap不保留插入顺序,而LinkedHashMap。这解释了mapmap2之间的输出差异。

1

如果你知道你使用int很容易。如果你不知道哪个原始类,你要使用的解决方案较为复杂,但没有更多

public static void thereAndBack(int[] keys, String[] values) { 
    // to map 
    Map<Integer, String> map = new HashMap<>(); 
    for (int i = 0; i < keys.length; i++) { 
     // int autobox to Integer 
     map.put(keys[i], values[i]); 
    } 

    // to array 
    int[] keys2 = new int[map.size()]; 
    String[] values2 = new String[map.size()]; 
    int i = 0; 
    for (Entry<Integer, String> entry : map.entrySet()) { 
     // Integer autobox to int 
     keys2[i] = entry.getKey(); 
     values2[i] = entry.getValue(); 
     i++; 
    } 
}