Ich bin neu in Java und sehr verwirrt.
Ich habe einen großen Datensatz mit der Länge 4 int[]
und möchte zählen, wie oft jede bestimmte Kombination von 4 Ganzzahlen auftritt. Dies ist dem Zählen von Worthäufigkeiten in einem Dokument sehr ähnlich.
Ich möchte eine erstellen Map<int[], double>
, die jedes int [] einer laufenden Anzahl zuordnet, während die Liste durchlaufen wird, aber Map akzeptiert keine primitiven Typen.
also habe ich gemacht Map<Integer[], Double>
Meine Daten werden als gespeichert, ArrayList<int[]>
daher sollte meine Schleife so etwas wie sein
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);
}
}
Ich bin mir nicht sicher, welchen Code ich im Kommentar benötige, damit dies funktioniert, um einen int[]
in einen zu konvertieren Integer[]
. Oder vielleicht bin ich grundlegend verwirrt über den richtigen Weg, dies zu tun.
quelle
Antworten:
Native Java 8 (eine Zeile)
Mit Java 8
int[]
kannInteger[]
leicht konvertiert werden:Wie andere sagten,
Integer[]
ist normalerweise kein guter Kartenschlüssel. Was die Konvertierung betrifft, haben wir jetzt einen relativ sauberen und nativen Code.quelle
List<Integer> list = IntStream.of(q).boxed().collect(Collectors.toList());
Integer[]
würde ich tatsächlich vorschlagen, folgende Syntax zu verwenden:Integer[] boxed = IntStream.of(unboxed).boxed().toArray();
In ähnlicher Weise wie @NwDxIntStream.of
ruftArrays.stream
trotzdem an. Ich denke, es kommt auf die persönlichen Vorlieben an - ich bevorzuge eine überschriebene Funktion, manche lieben es, explizitere Klassen zu verwenden.the "new" method (constructor) of the Integer[] class
.Wenn Sie ein
int[]
in ein konvertieren möchtenInteger[]
, gibt es im JDK keine automatisierte Möglichkeit, dies zu tun. Sie können jedoch Folgendes tun:Wenn Sie Zugriff auf die Apache lang- Bibliothek haben, können Sie die folgende
ArrayUtils.toObject(int[])
Methode verwenden:quelle
value
während die Indexvariable vorhandeni
ist.for (int i...)
Schleife wäre hier effizienter.Vermutlich soll der Schlüssel zur Karte mit dem Wert der Elemente anstelle der Identität des Arrays übereinstimmen. In diesem Fall möchten Sie eine Art Objekt, das definiert
equals
undhashCode
wie Sie es erwarten würden. Am einfachsten ist es, in eineList<Integer>
, eineArrayList
oder eine bessere Verwendung umzuwandelnArrays.asList
. Besser als das können Sie eine Klasse einführen, die die Daten darstellt (ähnlich,java.awt.Rectangle
aber ich empfehle, die Variablen als privates Finale und auch als Klassenfinale zu definieren).quelle
Verwenden einer regulären for-Schleife ohne externe Bibliotheken:
Konvertiere int [] in Integer []:
Konvertiere Integer [] in int []:
quelle
Ich habe mich in einer früheren Antwort geirrt. Die richtige Lösung besteht darin, diese Klasse als Schlüssel in der Map zu verwenden, die das eigentliche int [] umschließt.
und ändern Sie Ihren Code wie folgt:
quelle
Konvertiere int [] in Integer []
Konvertiere Integer [] in int []
quelle
newArray[i] = ids[i];
und im zweitennewArray[i] = WrapperArray[i]
:)Anstatt Ihren eigenen Code zu schreiben, können Sie einen IntBuffer verwenden, um das vorhandene int [] zu verpacken, ohne die Daten in ein Integer-Array kopieren zu müssen
IntBuffer implementiert vergleichbare Implementierungen, sodass Sie den bereits geschriebenen Code verwenden können. Formale Karten vergleichen Schlüssel so, dass a.equals (b) verwendet wird, um zu sagen, dass zwei Schlüssel gleich sind. Daher werden zwei IntBuffer mit dem Array 1,2,3 - selbst wenn sich die Arrays an verschiedenen Speicherorten befinden - als gleich bezeichnet Arbeite für deinen Frequenzcode.
}}
hoffentlich hilft das
quelle
Ich bin mir nicht sicher, warum Sie ein Double in Ihrer Karte benötigen. In Bezug auf das, was Sie versuchen, haben Sie ein int [] und möchten nur zählen, wie oft jede Sequenz auftritt? Warum sollte dies überhaupt ein Double erfordern?
Ich würde einen Wrapper für das int-Array mit den richtigen .equals- und .hashCode-Methoden erstellen, um die Tatsache zu berücksichtigen, dass das int [] -Objekt selbst die Daten in seiner Version dieser Methoden nicht berücksichtigt.
Verwenden Sie dann das Multiset von Google Guava, das genau zum Zählen von Vorkommen gedacht ist, sofern der von Ihnen eingegebene Elementtyp über die richtigen .equals- und .hashCode-Methoden verfügt.
Um dann die Anzahl für eine bestimmte Kombination zu erhalten:
quelle
IntArrayWrapper
definitiv der richtige Ansatz für die Verwendung einesint[]
Arrays als Hash-Schlüssel, aber es sollte erwähnt werden, dass ein solcher Typ bereits existiert . Sie können ihn zum Umschließen eines Arrays verwenden und haben ihn nicht nurhashCode
undequals
es ist sogar vergleichbar.Update: Obwohl das Folgende kompiliert wird, wird
ArrayStoreException
zur Laufzeit ein. Schade. Ich werde es für zukünftige Referenz bleiben lassen.Konvertieren eines
int[]
, in einInteger[]
:Ich muss zugeben, dass ich ein bisschen überrascht war, dass dies kompiliert wird
System.arraycopy
es sich um Lowlevel und alles handelt, aber es tut es. Zumindest in Java7.Sie können genauso einfach in die andere Richtung konvertieren.
quelle
Das hat wie ein Zauber gewirkt!
quelle
Konvertiere int [] in Integer []:
quelle
du brauchst nicht.
int[]
ist ein Objekt und kann als Schlüssel in einer Karte verwendet werden.ist die richtige Definition der Frequenzkarte.
Das war falsch :-). Die richtige Lösung wird auch gepostet :-).
quelle
frequencies.containsKey(q)
immer falsch zu sein, selbst wenn ichput
zweimal dasselbe Array habe. Gibt es hier einen Fehler, der Java's Definition der Gleichheit mit int [] betrifft?Verwenden Sie einfach:
quelle