2017-04-08 4 views
0

Ich habe Probleme, die folgenden zu arbeiten. Der Sinn dieser Aufgabe ist Ströme zu verwenden:Java, Collectors.toList() erstellt nur ein Element

Map<String, List<String>> descriptions = new HashMap<>(); 
wordArray[2] = "D1_E1^E2^E3^E4~D2_E1^E2"; 
if(wordArray[2].contains("~")) { 
    Arrays.stream(wordArray[2].split("~")) 
      .forEach(s -> descriptions.put(s.split("_")[0], 
        s.split("_")[1].contains("^") 
          ? Arrays.stream(s.split("_")[1].split("^")) 
            .collect(Collectors.toList()) 
           : Arrays.asList(s.split("_")[1]))); 
} 

Aus irgendeinem Grund dieses Collectors.toList() erzeugt nur einen String "E1^E2^E3^E4" statt separate Strings. Meine Vermutung ist, dass ich hier falsch liege: Arrays.stream(s.split("_")[1].split("^")), aber ich weiß nicht wo genau und wie es zu beheben ist. Mehr noch, weil das ganz gut funktioniert und dem obigen sehr ähnlich ist:

List<String> synonyms = new ArrayList<>(); 
wordArray[3] = "S1_S2_S3_S4"; 
synonyms = wordArray[3].contains("_") 
          ? Arrays.stream(wordArray[3].split("_")). 
            collect(Collectors.toList()) 
          : Arrays.asList(wordArray[3]); 

Vielen Dank!

+3

Der 'split()' Parameter ist ein regulärer Ausdruck, und '^' ist ein spezielles passendes Muster für den Anfang des Strings. Um auf '^' zu teilen, entkomme es, d. H. 'Split (" \\^")'. Wenn jedoch 'split()' mit etwas aufgerufen wird, das nicht in der Eingabe existiert, d.h. wenn 'contains()' return false ist, wird nur ein Ein-Element-Array mit der gesamten Eingabe zurückgegeben. Der 'contains()' Aufruf ist Zeitverschwendung. – Andreas

+1

Was ist Ihre erwartete Ausgabe? – developer

+0

@Andreas, danke, das war das Problem! Es funktioniert auch ohne den Aufruf 'contains()', also danke auch für diesen Tipp. –

Antwort

2

nicht sicher, was Ihre erwartete Ausgabe sollte sein, aber wenn es so etwas wie diese

[D1, E1, E2, E3, E4, D2, E1, E2]

dann einem Sie es aus dem Weg zu tun mit Java-Streams ist:

import java.util.List; 
import java.util.stream.Stream; 

import static java.util.stream.Collectors.toList; 

public class Parser { 
    public static void main(String[] args) { 
     String str = "D1_E1^E2^E3^E4~D2_E1^E2"; 
     List<String> strings = Parser.parseString(str); 
     System.out.println(strings); 
    } 

    public static List<String> parseString(String str) { 
     return Stream.of(str) 
       .map(s -> s.replaceAll("[_^~]", "-").split("-")) 
       .flatMap(Stream::of) 
       .collect(toList()); 
    } 
} 

von hier aus können Sie die Regex ausklammern und in parseString als zweites Argument übergeben, um mehr Flexibilität (falls erforderlich).

+0

Die Stream-API wird nicht benötigt, um die von Ihnen ausgeführte Zeichenfolgeverarbeitung zu erreichen. – scottb

+0

Natürlich nicht, aber wie in seiner Frage "Der Zweck dieser Aufgabe ist es, Streams zu verwenden", fragte er nach Stream-Ansatz. – artlovan

+0

Ohne Streams: 'return Arrays.asList (str.split (" [_^~] "));' – 4castle

Verwandte Themen