简体   繁体   English

在map中转换两个原始数组。 并将结果映射转换为该数组

[英]Convert two primitive arrays in map. and convert result map to that arrays

I have two arrays. 我有两个数组。 int and string . intstring How do I convert that arrays to map ? 如何将该数组转换为映射?

My code. 我的代码。 first of all, I have converted int to wrapper Integer 首先,我已将int转换为包装器Integer

   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;
    }

After that, I have converted two arrays into map 之后,我将两个数组转换为map

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;
    }

This is correct ? 这是对的 ? After that I need to convert in primitive arrays. 之后我需要转换原始数组。 how to do this ? 这个怎么做 ?

Example: 例:

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++;
}

But I need to implement this in method. 但我需要在方法中实现这一点。 How to do this ? 这个怎么做 ? And that is not all. 这还不是全部。 I need to convert result wrapper arrays in primitive. 我需要在原语中转换结果包装器数组。

May be, you tell me, how to implement it in your method ? 可能是,你告诉我,如何在你的方法中实现它?

  • First: I need to convert two primitive arrays in all map method (hashmap, treemap, linkedhashmap). 第一:我需要在所有map方法(hashmap,treemap,linkedhashmap)中转换两个原始数组。
  • Second: I need to convert result hashmap in my two primitive arrays. 第二:我需要在两个原始数组中转换结果hashmap。

if you know you're using int is easy. 如果你知道你使用int很容易。 If you don't know which primitive class you are going to use the solution is more complicated, but not much more 如果您不知道要使用哪个原始类,那么解决方案会更复杂,但不会更多

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++;
    }
}

If I'm guessing correctly, you want a generic method that receives a pair of arrays of primitive types and returns a specific map, with its keys and values matching those of the arrays. 如果我正确猜测,你需要一个接收一对基本类型数组的泛型方法,并返回一个特定的映射,其键和值与数组匹配。

Also, you want another method that receives a map and returns a pair of arrays of primitive types, with its elements matching the map's entries. 此外,您需要另一个接收映射并返回一对基本类型数组的方法,其元素与地图的条目匹配。

If these assumptions are correct, then you could try something like this to box your primitives: 如果这些假设是正确的,那么你可以尝试这样的方法来装箱你的原语:

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);
}

Then, you could implement a generic toMap() method as follows: 然后,您可以实现一个通用的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));
}

This collects a stream to a map by iterating on the keys and values arrays, putting each respective pair of elements on the map provided by the factory argument. 这通过迭代keysvalues数组将一个流收集到地图,将每个相应的元素对放在factory参数提供的地图上。 This factory is actually a Supplier that will be used to create a concrete map implementation, ie HashMap , TreeMap , LinkedHashMap , etc. factory实际上是一个Supplier ,将用于创建具体的地图实现,即HashMapTreeMapLinkedHashMap等。

Note that you might loose elements order if the map implementation does not preserve insertion order, such as it happens with HashMap . 请注意,如果地图实现不保留插入顺序,则可能会丢失元素顺序,例如HashMap

For the reverse operation, you'd need a helper class that would hold two arrays: 对于反向操作,您需要一个可以容纳两个数组的辅助类:

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;
}

This is a simple pair holder. 这是一个简单的配对。 Then, you could transform a given map to a pair of arrays as follows: 然后,您可以将给定的映射转换为一对数组,如下所示:

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);
}

This creates the keys and values arrays by streaming on the given map's keySet() and values() collection, respectively. 这通过分别在给定映射的keySet()values()集合上流式传输来创建keysvalues数组。 Respective IntFunction s playing the role of factories for the arrays are provided. 提供了相应的IntFunction扮演着阵列工厂的角色。 This is to make generics mechanics work as expected, otherwise you wouldn't be able to fix arrays' elements generic types to map's keys and values' generic types. 这是为了使泛型机制按预期工作,否则您将无法修复数组元素泛型类型以映射键和值的泛型类型。

Within the Pair class, you cannot hold primitive arrays, since it is generic, and (by Sept 2015) it is still not allowed to use primitive types as type parameters. Pair类中,你不能保存原始数组,因为它是通用的,并且(截至2015年9月)仍然不允许使用原始类型作为类型参数。

So we need several unbox methods: 所以我们需要几个unbox方法:

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

Finally, here's an example that shows how this code could be used: 最后,这是一个显示如何使用此代码的示例:

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]

There are no streams for floats, booleans, shorts, chars neither bytes in Java, so you have to use a couple of workarounds. Java中没有用于浮点数,布尔值,短路,字符和流的字节流,因此您必须使用几种解决方法。

Generics syntax is not very clear, but it lets you fix generic types, such as I did with keys and values of a map. 泛型语法不是很清楚,但它允许您修复泛型类型,例如我使用键和映射值。

A final note: HashMap doesn't preserve insertion order, while LinkedHashMap does. 最后一点: HashMap不保留插入顺序,而LinkedHashMap则保留。 This explains the difference in the output between map and map2 . 这解释了mapmap2之间输出的差异。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM