Datentypen ArrayUtils.indexOf( ... ) liefert -1 obwohl Wert scheinbar enthalten ist

Taste

Bekanntes Mitglied
Hallo zusammen,

vielleicht findet jemand von Euch meinen Fehler...

Ich habe ein Array von Strings wie in diesem Beispiel:
Java:
import org.apache.commons.lang.ArrayUtils;
public class Test
{
   public static void main( String[] args )
   {
      String[] headers = { "abbreviation", "name", "remarks" };

      System.out.println( ArrayUtils.indexOf( headers, "abbreviation" ) );
   }
}
Dies läuft ohne Probleme und ich bekomme die Ausgabe "0". So weit so gut und klar.

Nun kommt bei mir der Inhalt des Arrays allerdings aus einer geparsten csv-Datei und im Debugger sieht auch alles gut aus (Schreibweise korrekt, keine Leerzeichen...).
Allerdings führt der Aufruf von:
Java:
ArrayUtils.indexOf( headers, "abbreviation" )
zu dem Rückgabewert "-1".

Was kann da schieflaufen? Evtl ein Problem mit dem Encoding der csv-Datei??? Ich bin gerade ein wenig ratlos ;-)

Beste Grüße,
Nick
 

Michael...

Top Contributor
kenne leider die Implementierung der Utils Methode nicht. Kannst Du da in den Code reinschaun. Eventuell prüft diese auf Identität, also ==, und setzt das es sich um ein und das selbe Objekt handelt.
 

Taste

Bekanntes Mitglied
Hallo Michael,

hier ein Auszug der Methode (Quelle: http://www.docjar.com/html/api/org/apache/commons/lang/ArrayUtils.java.html):

1575 /**
1576 * <p>Finds the index of the given object in the array starting at the given index.</p>
1577 *
1578 * <p>This method returns {@link #INDEX_NOT_FOUND} (<code>-1</code>) for a <code>null</code> input array.</p>
1579 *
1580 * <p>A negative startIndex is treated as zero. A startIndex larger than the array
1581 * length will return {@link #INDEX_NOT_FOUND} (<code>-1</code>).</p>
1582 *
1583 * @param array the array to search through for the object, may be <code>null</code>
1584 * @param objectToFind the object to find, may be <code>null</code>
1585 * @param startIndex the index to start searching at
1586 * @return the index of the object within the array starting at the index,
1587 * {@link #INDEX_NOT_FOUND} (<code>-1</code>) if not found or <code>null</code> array input
1588 */
1589 public static int indexOf(Object[] array, Object objectToFind, int startIndex) {
1590 if (array == null) {
1591 return INDEX_NOT_FOUND;
1592 }
1593 if (startIndex < 0) {
1594 startIndex = 0;
1595 }
1596 if (objectToFind == null) {
1597 for (int i = startIndex; i < array.length; i++) {
1598 if (array == null) {
1599 return i;
1600 }
1601 }
1602 } else {
1603 for (int i = startIndex; i < array.length; i++) {
1604 if (objectToFind.equals(array)) {
1605 return i;
1606 }
1607 }
1608 }
1609 return INDEX_NOT_FOUND;
1610 }

es wird mit "equals" verglichen (Zeile 1604), also sollte es daran nicht liegen, oder?

Gruß, Nick

PS: Sorry für die mangelnde Formatierung ;-)
 
S

SlaterB

Gast
kopiere dir die Methode in dein Programm bzw. programmiere selber eine Schleife
bzw. lade nur ein Element aus einer CSV-Datei/ schaue alternativ vorher nach welcher Index es ist, hole dir das Element aus dem Array, aus dem CSV in eine Variable:
Java:
String csvElement = ...;
String gesucht = "abbreviation";
so und jetzt equals aufrufen, was kommt raus?
wie ist die Länge beider Strings?
notfalls per Schleife durchgehen, jeden char zum Index holen und paarweise vergleichen, auf int casten,
 

Michael...

Top Contributor
OK. Dann sieht es so aus, dass die Zeichenketten unterschiedliche Zeichen enthalten. Sicher dass da keine Leerzeichen/Zeilenumbrüche drin sind.
Ausser Debuggen und Analysen via System.out fällt mir da nicht viel dazu ein.
 

Taste

Bekanntes Mitglied
@Slater:

Okay, vor lauter Verzweiflung hab ich es getestet, wie Du vorgeschlagen hast:
Java:
      if( headers != null )
      {
         for( String header : headers )
         {
            System.out.println( "'" + Service.SERVICE_ATTRIBUTE_ABBREVATION + "' (constant)" );
            System.out.println( "'" + header + "' (array-value)" );
            System.out.println( "equals: " + Service.SERVICE_ATTRIBUTE_ABBREVATION.equals( header ) );
         }
      }

Die Ausgabe dazu:
Code:
'abbreviation' (constant)
'abbreviation' (array-value)
equals: false
'abbreviation' (constant)
'name' (array-value)
equals: false
'abbreviation' (constant)
'remarks' (array-value)
equals: false

Ich verstehe es nicht... Heute scheint so ein richtiger Freitag zu sein ;)
 

Taste

Bekanntes Mitglied
Hallo,

ja, ich hab das Ganze gerade noch mal geändert in:
Java:
      if( headers != null )
      {
         for( String header : headers )
         {
            System.out.println( "'" + "abbreviation" + "' (constant)" );
            System.out.println( "'" + header + "' (array-value)" );
            System.out.println( "equals: " + "abbreviation".equals( header ) );
         }
      }

Ausgabe ist die Gleiche...
 
S

SlaterB

Gast
du machst eine Hälfte, hörst dann aber auf, worin liegt da der tiefere Sinn?
wenn ich weiß, dass die Glühbirne geht und die Steckdose auch (Schlag, lass nach..) dann teste ich doch mal eine andere Lampe,

hier ist die gesamte equals-Methode:
Java:
   public boolean equals(Object anObject) {
	if (this == anObject) {
	    return true;
	}
	if (anObject instanceof String) {
	    String anotherString = (String)anObject;
	    int n = count;
	    if (n == anotherString.count) {
		char v1[] = value;
		char v2[] = anotherString.value;
		int i = offset;
		int j = anotherString.offset;
		while (n-- != 0) {
		    if (v1[i++] != v2[j++])
			return false;
		}
		return true;
	    }
	}
	return false;
    }
auch diesen Quellcode kannst du kopieren und in die Schleifen oder Bedingungen reingehen und schauen wo es hakt,
ok, nicht ganz dieser Quellcode, verwendet interne Attribute, aber length(), toCharArray() usw. sollten klar sein

habe ich aber schon genau geschrieben..
danke für Notwendigkeit zur Wiederholung (ohne Verständnisfrage oder ähnliches)
 

Taste

Bekanntes Mitglied
Hallo,

tut mir leid, Dich strapaziert zu haben, dies war gewiss nicht meine Absicht. Ich hab die Antwort nicht präzise genug formuliert:

Ich habe natürlich die "equals"-Methode der String-Klasse debugged und dabei festgestellt, dass die Länge der Strings unterschiedlich ist.

Wenn ich mir die ursprüngliche csv-Datei allerdings in einem Editor (Notepad++) ansehe und dabei alle Zeichen anzeigen lasse, so erkenne ich dennoch nichts was zu diesem Unterschied führen könnte (Codierung: UTF-8).

Sorry nochmal für die notwendige Wiederholung!

Gruß und Dank,
Nick
 

Bernd Hohmann

Top Contributor
Ich hab da so einen Verdacht: die csv-Datei hat einen Unicode-Header (oder wie immer das heisst).

Schau doch mal mit einem Hex-Viewer in die Datei ob da am Anfang sowas wie FF FE steht.

Bernd
 

Taste

Bekanntes Mitglied
Hallo Bernd,

ja das ist eine Spur. Da steht: "ef bb bf".

Tut mir leid, wenn ich jetzt etwas naiv fragen muss, aber kannst Du mir sagen wie ich das loswerde bzw. korrekt handle?

Gruß und Dank,
Nick
 
S

SlaterB

Gast
ich habe den Fehler nun auch, man kann ihn aus den Ausgaben hier im Forum übernehmen:

Java:
public class Test
{
    public static void main(String[] args)
    {
        String test1 = "abbreviation";
        String test2 = "abbreviation";
        System.out.println(test1.equals(test2));
        System.out.println(test1.length());
        System.out.println(test2.length());
        for (int i = 0; i < 12; i++)
        {
            char a = test1.charAt(i);
            char b = test2.charAt(i);
            System.out.println("i: " + i + ", " + a + ", " + b + " -- " + (int)a + ", " + (int)b);
        }
    }
}
Ausgabe:
Code:
false
12
13
i: 0, a,  -- 97, 65279
i: 1, b, a -- 98, 97
i: 2, b, b -- 98, 98
i: 3, r, b -- 114, 98
i: 4, e, r -- 101, 114
i: 5, v, e -- 118, 101
i: 6, i, v -- 105, 118
i: 7, a, i -- 97, 105
i: 8, t, a -- 116, 97
i: 9, i, t -- 105, 116
i: 10, o, i -- 111, 105
i: 11, n, o -- 110, 111
13. Zeichen im zweiten String noch nicht angeschaut,
aber man sieht sofort, dass es das erste Zeichen im test2-String ist

im Eclipse-Editor kann man auch an die entsprechende Stelle gehen und einmal auf 'Entf' klicken ohne dass etwas passiert, verrückt,
hier im Forum-Browser-Editor ebenso keine Anzeige, der Entf-Effekt immerhin wenn man vor dem " beginnt,
im NotePad++-Editor wird gleich ein Fragezeichen angezeigt, viel besser,


wie das mit der CSV-Datei zusammenhängt kann ich persönlich nicht ergründen,
trim() von String hilft nicht, da müsste man schon eine Methode schreiben die solche ungewöhnlichen chars, > 60000 bzw. einfach genau diesen Wert auf Blacklist, findet und herausschneidet
 
Zuletzt bearbeitet von einem Moderator:

Bernd Hohmann

Top Contributor
Die Frage ist gar nicht so naiv: Ich habe hier ein ähnliches Problem wenn User Dateien mit NotePad bearbeiten und bekomme es nur weg, indem ich den Kram in die Zwischenablage kopiere und in eine neue Datei einfüge (in einem Editor, der kein Unicode kann).

Eine brauchbare Lösung für Java hab ich noch nicht gefunden (bzw. noch nicht ernsthaft gesucht).

Bernd
 

Bernd Hohmann

Top Contributor
So, jetzt weiss ich auch wieder um was es ging: das Zeug am Anfang der Datei ist die "Unicode byte order mark" (BOM)

Java: a rough guide to character encoding

Ich hab mich mal durch new BufferedReader(new FileInputStream(...)).readLine() durchgesteppt.

Dejure macht Java 6 da einen riesen Zirkus um Unicode korrekt zu behandeln, depraxi kommt bei mir bei den BOM für UTF-8, Unicode, UnicodeBigendian nur Schrott beim Lesen heraus.

Hmpf.

Bernd
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A ArrayList: indexOf funzt nich Allgemeine Java-Themen 5
M Hilfe beim substring, indexOf, etc. Allgemeine Java-Themen 8
T indexOf => bestimmter Bereich Allgemeine Java-Themen 26
8u3631984 Argument Captor liefert NULL zurück Allgemeine Java-Themen 2
DiekleineRatte77 Schlüsselworte ANSI Konverter liefert UTF-8 Allgemeine Java-Themen 7
Arif Math.cos liefert komische Werte Allgemeine Java-Themen 8
I HTML einer Website auslesen liefert nur head Allgemeine Java-Themen 6
A Datentypen Long.valueOf liefert kein "L" am Ende Allgemeine Java-Themen 3
T Variablenübergabe liefert immer null Allgemeine Java-Themen 13
C Object.equals() liefert falschen Wert? Allgemeine Java-Themen 14
Q GregorianCalendar Methode add liefert komische Werte Allgemeine Java-Themen 3
T SimpleDateFormat.parse() liefert falschen Tag Allgemeine Java-Themen 2
T java.uil.Random liefert negative Werte Allgemeine Java-Themen 2
I newInstance() liefert null zurück Allgemeine Java-Themen 4
Z new Date() liefert falsche Uhrzeit Allgemeine Java-Themen 12
S Newton-Verfahren liefert nur 1 Wert Allgemeine Java-Themen 3
J Liefert new URL(String) gecachte Webseiten? Allgemeine Java-Themen 15
S HashMap containsKey liefert immer false zurück Allgemeine Java-Themen 15
M Kugelschnittberechnung liefert falsche Werte Allgemeine Java-Themen 4
A md5 liefert unterschiedliche Testsummen? Allgemeine Java-Themen 4
S FOP liefert fehlerhafte PDF Allgemeine Java-Themen 13
S instanceof liefert true, aber cast funktioniert nicht! Allgemeine Java-Themen 6
MasterEvil File.createTempFile liefert nur kurzen Pfad mit Tilde Allgemeine Java-Themen 3
M BufferedReader.read(char[] cbuf) liefert falsche Werte? Allgemeine Java-Themen 4
N contains(.) liefert nicht erwartetes Ergebnis Allgemeine Java-Themen 3
H JNI: loadLibrary liefert UnsatisfiedLinkError Allgemeine Java-Themen 2
J Base64 Kodierung liefert korrupte Dateien Allgemeine Java-Themen 3
S ´Locale.getDefault() liefert en Allgemeine Java-Themen 10
C ImageIO die read-Methode liefert mir ein null- Wert zurück Allgemeine Java-Themen 10
S aFile.delete() liefert false - Gründe ? Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben