Hadoop: Как я могу получить массив значений типа double в паре ключ-значение? - PullRequest
2 голосов
/ 18 февраля 2012

У меня есть проблема, где мне нужно объединить несколько векторов, чтобы найти статистику.Например, у меня есть векторы двойников, и мне нужно их сложить.Мои векторы выглядят так:

      1,0,3,4,5
      2,3,4,5,6
      3,4,5,5,6

Мои пары ключ-значение до сих пор (String, String).Но каждый раз, когда мне нужно добавить эти векторы, я сначала должен преобразовать их в двойные массивы, сложить их и, наконец, преобразовать совокупный вектор в строку.Я думаю, что было бы намного быстрее, если бы я просто мог иметь пары ключ-значение в форме (String, двойной массив).Там не будет необходимости конвертировать их туда и обратно.Моя проблема в том, что я не могу найти способ использовать двойные массивы в качестве значения.Есть ли более простой способ, чем создать новый пользовательский тип?

1 Ответ

3 голосов
/ 18 февраля 2012

Вы имеете в виду что-то вроде этого?

Map<String, List<Double>> arrays = new HashMap<String, List<Double>>();

double[] array;
arrays.put("ArrayKey", Arrays.asList(array));

тогда вы можете вызвать метод вашей карты:

map(String key, String arrayKey) {
    List<Double> value = arrays.get(arrayKey);
}

Также вы можете сериализовать ваш двойной массив, а затем десериализовать его обратно:

package test;

import org.apache.commons.codec.binary.Base64InputStream;
import org.apache.commons.codec.binary.Base64OutputStream;

import java.io.*;
import java.util.Arrays;

public class Test {

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        double[] array = {0.0, 1.1, 2.2, 3.3};
        String stringValue = serialize(array);
        map("Key", stringValue);
    }

    public static void map(String key, String value) throws ClassNotFoundException, IOException {
        double[] array = deserialize(value);
        System.out.println("Key=" + key + "; Value=" + Arrays.toString(array));
    }

    public static String serialize(double[] array) throws IOException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        Base64OutputStream base64OutputStream = new Base64OutputStream(byteArrayOutputStream);
        ObjectOutputStream oos = new ObjectOutputStream(base64OutputStream);
        oos.writeObject(array);
        oos.flush();
        oos.close();
        return byteArrayOutputStream.toString();
    }

    public static double[] deserialize(String stringArray) throws IOException, ClassNotFoundException {
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(stringArray.getBytes());
        Base64InputStream base64InputStream = new Base64InputStream(byteArrayInputStream);
        ObjectInputStream iis = new ObjectInputStream(base64InputStream);
        return (double[]) iis.readObject();
    }
}

ВЫХОД:

Key=Key; Value=[0.0, 1.1, 2.2, 3.3]

Отображение выполняется быстрее, но сериализация будет более полезной, если вы будете использовать для этого узлы и кластеры (если вам нужно передать свои массивы в другую JVM):

 private static class SpeedTest {
        private static final Map<String, List> arrays = new HashMap<String, List>();

        public static void test(final double[] array) throws IOException, ClassNotFoundException {
            final String str = serialize(array);
            final int amount = 10 * 1000;

            long timeStamp = System.currentTimeMillis();
            for (int i = 0; i < amount; i++) {
                serialize(array);
            }
            System.out.println("Serialize: " + (System.currentTimeMillis() - timeStamp) + " ms");

            timeStamp = System.currentTimeMillis();
            for (int i = 0; i < amount; i++) {
                deserialize(str);
            }
            System.out.println("Deserialize: " + (System.currentTimeMillis() - timeStamp) + " ms");

            arrays.clear();
            timeStamp = System.currentTimeMillis();
            // Prepaire map, that contains reference for all arrays.
            for (int i = 0; i < amount; i++) {
                arrays.put("key_" + i, Arrays.asList(array));
            }
            // Getting array by its key in map.
            for (int i = 0; i < amount; i++) {
                arrays.get("key_" + i).toArray();
            }
            System.out.println("Mapping: " + (System.currentTimeMillis() - timeStamp) + " ms");
        }
    }

ВЫХОД:

Serialize: 298 ms
Deserialize: 254 ms
Mapping: 27 ms
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...