Как я могу использовать массивы MATLAB в качестве ключей к объектам HashMap java?

Я думаю, что это определенно стоит времени и усилия изучить энергию. Мне это делает ввод и навигацию вокруг текста настолько эффективными, трудно предположить возвращаться к emacs или ctrl/shift/alt/meta ключевым комбинациям.

не становятся запуганными всеми необычными функциями энергии. Как только Вы использовали его достаточно, Вы выясните, какие команды Вы используете большинство, и Вы выясните, о каких вещах можно забыть.

10
задан gnovice 29 August 2009 в 23:11
поделиться

4 ответа

Я думаю, проблема в том, что примитивные массивы Java не предоставляют вам правильных equals () и hashCode (). Они используют стандартные методы Object, которые сравнивают по идентификатору объекта, а не по содержащимся значениям. При использовании нескалярных массивов в качестве ключей в HashMap, Matlab преобразует их в double [], но они будут отдельными объектами Java, поэтому они получат такое поведение.

Если вы обернули значения массива в объект Java, который обеспечивается поведение по значению для equals () и hashCode () перед их использованием в качестве ключей, это может сработать. К счастью, java.util.Arrays предоставляет реализации по значению для примитивных массивов. Нам просто нужно вставить их в класс-оболочку, который предоставляет интерфейс, который ожидает HashMap.

package test;
import java.util.Arrays;

/**
 * A double[] that with by-value semantics for equals() and hashCode() so you
 * can use it in HashMaps.
 * In a non-toy class, you'd probably use switch statements to support arrays
 * of any primitive type. In a language with real generics, you'd just template
 * this.
 */
public class EqualByValueDoubleArray {
    private double[] x;
    public EqualByValueDoubleArray(double[] x) { this.x = x; }
    public double[] getArray() { return x; };
    public boolean equals(Object obj) {
        if (obj instanceof EqualByValueDoubleArray) {
            return Arrays.equals(this.x, ((EqualByValueDoubleArray)obj).x);
        } else {
            return false;
        }
    }
    public int hashCode() { return Arrays.hashCode(x); }
}

Теперь вы можете обернуть их и использовать как ключи от Matlab.

function scratch_array_keyed_hashmap
import test.EqualByValueDoubleArray;
map = java.util.HashMap;
a = [1 2 3 4 5]';

key = EqualByValueDoubleArray(a);
map.put(key, 'my value');
% Separate key so we know it's comparing by value, not Java object identity
key2 = EqualByValueDoubleArray(a);
gotBack = map.get(key2)

Для меня это работает под R2008b.

6
ответ дан 4 December 2019 в 03:16
поделиться

Я не думаю, что вы можете использовать числовые векторы или матрицы в качестве ключей в хэш-карте Java. Вместо этого вам придется преобразовать вектор или матрицу в один уникальный ключ, например в уникальное символьное строковое представление значений в векторе или матрице. Есть несколько способов сделать это:

  • Для целочисленных массивов вы можете использовать функцию CHAR , чтобы преобразовать целые числа в их эквивалентные представления ASCII, создав таким образом строку символов. Это будет эффективно работать только для целочисленных значений от 0 до 65535, поскольку все, что находится за пределами этого диапазона, скорее всего, будет иметь неопределенное поведение. Вот пример:

     X = [1 2 3; 4 5 6]; % X - это матрица 2 на 3
    keyValue = char (X (:) '); % Преобразовать X в вектор-строку и преобразовать в ASCII
    

    Для целых значений, слишком больших для использования CHAR, вы можете использовать вместо него INT2STR :

     keyValue = int2str (X (:) ');
    
  • Для массивов с плавающей запятой можно использовать функцию NUM2STR для создания форматированного строкового представления каждого из элементов массива, объединенных вместе. Вот пример:

     X = rand (2,3) * 9999; % X - это матрица случайных двойных значений размером 2 на 3
    keyValue = num2str (X (:) ','% 10.5f ');
    

    Чтобы гарантировать уникальность ключа (избегая округления значения с плавающей запятой), вы можете вместо этого преобразовать двойные значения в их полные 64-битные двоичные представления, используя DEC2BIN . Однако это, скорее всего, приведет к огромным символьным клавишам:

     keyValue = reshape (dec2bin (X (:), 64) ', 1, []);
    

Одним из недостатков этих опций является то, что ваши ключи потенциально могут оказаться довольно длинными строками символов. Я не уверен, существует ли верхний предел количества символов в ключе или есть снижение производительности при использовании длинных строк символов для ключей.

1
ответ дан 4 December 2019 в 03:16
поделиться

Если вы используете более новую версию MATLAB (я думаю, 2008b или новее), то MATLAB имеет свой собственный класс карты, который работает для определенных типов ключей. См. Документацию: контейнеры.Карта

-1
ответ дан 4 December 2019 в 03:16
поделиться

Структуры Matlab обеспечивают очень быстрый поиск по буквенно-цифровым клавишам (ну, [a-zA-Z] [a-zA-Z_0-9] * сопоставление); в противном случае, если вы пытаетесь хешировать числа, я бы предложил использовать разреженные массивы с удвоением массива; пусть значение массива указывает на индекс того, что вы пытаетесь найти. hth

0
ответ дан 4 December 2019 в 03:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: