Я новичок в Java и очень смущен.
У меня большой набор данных длиной 4 int[]
и я хочу подсчитать, сколько раз встречается каждая конкретная комбинация из 4 целых чисел. Это очень похоже на подсчет частот слов в документе.
Я хочу создать Map<int[], double>
который отображает каждое значение int [] на счетчик при переборе списка, но Map не принимает примитивные типы.
так что я сделал Map<Integer[], Double>
мои данные хранятся в виде, ArrayList<int[]>
так что мой цикл должен быть что-то вроде
ArrayList<int[]> data = ... // load a dataset`
Map<Integer[], Double> frequencies = new HashMap<Integer[], Double>();
for(int[] q : data) {
// **DO SOMETHING TO convert q from int[] to Integer[] so I can put it in the map
if(frequencies.containsKey(q)) {
frequencies.put(q, tfs.get(q) + p);
} else {
frequencies.put(q, p);
}
}
Я не уверен, какой код мне нужен в комментарии, чтобы сделать эту работу для преобразования int[]
в Integer[]
. Или, может быть, я в корне не понимаю, как сделать это правильно.
java
arrays
generics
collections
Jonik
источник
источник
Ответы:
Родная Java 8 (одна строка)
С помощью Java 8
int[]
можно легко преобразоватьInteger[]
:Как говорили другие,
Integer[]
обычно это не очень хороший ключ карты. Но что касается преобразования, у нас теперь есть относительно чистый и нативный код.источник
List<Integer> list = IntStream.of(q).boxed().collect(Collectors.toList());
Integer[]
я бы на самом деле предложил использовать следующий синтаксис:Integer[] boxed = IntStream.of(unboxed).boxed().toArray();
аналогично @NwDxIntStream.of
звонитArrays.stream
. Я думаю, что это сводится к личным предпочтениям - я предпочитаю одну переопределенную функцию, некоторые любят использовать более явный класс.the "new" method (constructor) of the Integer[] class
.Если вы хотите преобразовать a
int[]
в aInteger[]
, в JDK нет автоматизированного способа сделать это. Тем не менее, вы можете сделать что-то вроде этого:Если у вас есть доступ к библиотеке Apache lang , вы можете использовать такой
ArrayUtils.toObject(int[])
метод:источник
value
то время как переменная индексацииi
есть.for (int i...)
цикл был бы более эффективным здесь.Предположительно, вы хотите, чтобы ключ на карте соответствовал значению элементов, а не идентичности массива. В этом случае вы хотите какой-то объект, который определяет
equals
иhashCode
как вы ожидаете. Проще всего конвертировать вList<Integer>
,ArrayList
или лучше использоватьArrays.asList
. Более того, вы можете ввести класс, представляющий данные (аналогично,java.awt.Rectangle
но я рекомендую сделать переменные private final, а также final класс).источник
Использование обычного цикла for без внешних библиотек:
Преобразуйте int [] в Integer []:
Преобразовать целое число [] в int []:
источник
Я был неправ в предыдущем ответе. Правильное решение состоит в том, чтобы использовать этот класс в качестве ключа в карте, оборачивая фактическое int [].
и измените свой код следующим образом:
источник
Конвертировать int [] в Integer []
Преобразовать целое число [] в int []
источник
newArray[i] = ids[i];
а во второмnewArray[i] = WrapperArray[i]
:)Вместо того, чтобы писать свой собственный код, вы можете использовать IntBuffer для переноса существующего int [] без необходимости копировать данные в массив Integer.
IntBuffer реализует сопоставимые возможности, поэтому вы можете использовать уже написанный код. Формально карты сравнивают ключи так, что a.equals (b) используется, чтобы сказать, что два ключа равны, поэтому два IntBuffers с массивом 1,2,3 - даже если массивы находятся в разных местах памяти - называются равными и поэтому будут работать на свой частотный код.
}
надеюсь, это поможет
источник
Не уверен, почему вам нужен двойник на вашей карте. С точки зрения того, что вы пытаетесь сделать, у вас есть int [], и вы просто хотите подсчитать, сколько раз встречается каждая последовательность? В любом случае, для чего это нужно?
Я хотел бы создать оболочку для массива int с соответствующими методами .equals и .hashCode, чтобы учесть тот факт, что сам объект int [] не учитывает данные в своей версии этих методов.
А затем используйте мультисет Google Guava, который предназначен именно для подсчета вхождений, при условии, что тип элемента, который вы в него вставили, имеет надлежащие методы .equals и .hashCode.
Затем, чтобы получить счет для любой конкретной комбинации:
источник
IntArrayWrapper
определенно правильный подход для использованияint[]
массива в качестве хеш-ключа, но следует отметить, что такой тип уже существует ... Вы можете использовать его для обёртывания массива, а не только иметь его,hashCode
иequals
он даже сопоставим.Обновление: хотя приведенная ниже компиляция, она выдает
ArrayStoreException
во время выполнения. Жаль. Я оставлю это на будущее.Преобразование
int[]
, вInteger[]
:Я должен признать, что я был немного удивлен, что это компилируется, учитывая
System.arraycopy
низкоуровневость и все такое, но это так. По крайней мере, в Java7.Вы можете конвертировать другой способ так же легко.
источник
Это работает как шарм!
источник
Преобразуйте int [] в Integer []:
источник
тебе не нужно
int[]
является объектом и может использоваться в качестве ключа внутри карты.является правильным определением карты частот.
Это было неправильно :-). Правильное решение тоже выложено :-).
источник
frequencies.containsKey(q)
, всегда будет ложным, даже если у меняput
дважды один и тот же массив - есть ли здесь какой-то сбой, связанный с определением java равенства с int []?Просто используйте:
источник