Stream Array List - Frage

werdas34

Bekanntes Mitglied
Hallo,

meine Aufgabe ist es eine Datei mittels Stream einzulesen und dann in eine Map zu packen.
Inhalt der Datei:
Baywa, Gruberstr. 60B 85586 Poing, Alcohol, Gardening Tools, Plants
Rewe, Saturnstr. 61 85609 Aschheim, Food, Sanitary Products, Beverage
Conrad, Tal 29 80331 Muenchen, Computer, Electronic
Aldi Sued, Muenchener Str. 34 85560 Ebersberg, Food, Gardening Tools, Sanitary Products, Beverage
Die Map soll so aufgebaut werden Map<Corporations, List<String>>. Corporations beinhaltet den Namen der Firma und die Adresse. In die Liste sollen die Kategorien, die die Firma anbietet.
Der erste Schritt: das einlesen:
Code:
        Path path = Paths.get("corporations.txt");
       Files.lines(path)
Nur weiß ich nicht wie ich den Stream splitten soll. es ginge mit
Code:
       .forEach(n -> n.split(", "));
Nur kann ich damit dann nichts anfangen, da das ein terminierender Operator ist und ich die Ausgabe nicht in einer Variable speichern kann.

Und dann kommt mein nächstes Problem. Wenn ich dann die 4 splitArrays hätte, wie schreibe ich mit Lambda und Stream einen Ausdruck der, die Liste mit Artiklen füllt. Position 0 und 1 sind für das Corporation Objekt, aber dann der Rest, wie mach ich das? mit .skip(2)?

Es soll auschließlich Lambda/Stream verwendet werden. Ohne diese Java8 Neuerungen habe ich die Aufgabe bereits gelöst-

thx
mfg werdas34
 
Denke es gibt eine bessere Lösung, aber vielleicht hilft es ja:
https://repl.it/@game4you/StreamToMap

Java:
import java.nio.file.*;
import java.util.stream.*;
import java.util.*;
class Main {
  public static void main(String[] args) {
    try{
      Path path = Paths.get("corporations.txt");
      Map<Corp,List<String>> m = Files.lines(path).map(s -> Arrays.asList(s.split(","))).
      collect(
        Collectors.toMap(
          data -> new Corp(
              data.get(0), data.get(1)
          ),
          data -> data.subList(2, data.size())
        )
      );
      m.entrySet().stream().forEach(System.out::println);    
    }catch(Exception e){
      e.printStackTrace();
    }
  }
}
 
Danke. Hat super funktioniert.

Habe jetzt ein ähnliches Problem.
Aufgabe:
Lese aus einer Datei die Stadtnamen aus und der erste Eintrag ist ein Knoten und die weiteren Städte sind die Nachbarsstädte zu denen eine Verbindung besteht.
Diese Verbindung ist symmetrisch. Heißt StadtA hat Verbindung zu StadtB dh. also auch der Knoten StadtB hat eine Verbinung zu StadtA.
In der Datei wird nur einmal eine Verbindung erwähnt. Da die weiteren dann automatisch zwecks symmetrie erfolgen.
Dateiinhalt:
Code:
Regensburg Passau Nuernberg Muenchen Augsburg
Nuernberg Augsburg Wuerzburg
Muenchen Passau Augsburg
Passau
Augsburg Wuerzburg
Wuerzburg
Aufgabe: 1. Löse dies mit Mitteln aus Java7. Habe ich bereits.
2. Aufgabe Schreibe eine zweite Factory-Methode make nur mit Lambda/Streams
Bei zweitens hänge ich:
Hier mal der gesamte Code: (Objektvariablen und Funktionsköpfe sind so vorgebenen)
Code:
public class Graph {
    private final Map<String, Set<String>> nodesToConnections = new HashMap<>();

    // a) Stadt einfügen in Map wenn noch nicht enthalten
    public void addNode(String node) {
        if (!nodesToConnections.containsKey(node)) {
            nodesToConnections.put(node, new HashSet<>());
        }
    }

    // b) Verbindungen zwischen den Städten machen - symmetisch
    public void addConnection(String from, String to) {
        Set<String> setFrom = nodesToConnections.get(from);
        setFrom.add(to);
        nodesToConnections.put(from, setFrom);
        Set<String> setTo = nodesToConnections.get(to);
        setTo.add(from);
        nodesToConnections.put(to, setTo);
    }

    //c)
    public static Graph make(Path file) throws IOException {
        Graph graph = new Graph();
        try {
        List<String> lines = Files.readAllLines(file);
        for (int i = 0; i < lines.size(); i++) {
            String[] splitLine = lines.get(i).split(" ");
            graph.addNode(splitLine[0]);
        }
        for (int i = 0; i < lines.size(); i++) {
            String[] splitLine = lines.get(i).split(" ");
            if (splitLine.length > 1) {
                for (int j = 1; j < splitLine.length; j++) {
                    graph.addConnection(splitLine[0], splitLine[j]);
                }
            }
        }
        }catch(Exception e) {
           e.printStackTrace();
        }
        return graph;
    }
    //d)
    public static Graph make2(Path file) throws IOException {
        Graph graph = new Graph();
         graph.nodesToConnections = Files.lines(file)
                  .map(s -> Arrays.asList(s.split(" ")))
                  .collect(
            Collectors.toMap(
              data -> data.get(0),
              data ->  ));
      
      
      
        return graph;
    }
  
    public static void main(String[] args) throws IOException {
        Graph graph = Graph.make(Paths.get("Graph.txt"));
        System.out.println(graph.nodesToConnections.entrySet());
    }

}

Das Problem ist das ich nicht weiß, wie ich die Map values fülle. Beim ersten mal habe ich ne weitere Schleife genommen und dann immer die jeweiligen Verbindungen gesetzt. Aber wie setze ich das in Streams um ?

thx
mfg werdas34
 
Indem Du die Methoden von Graph verwendest.
Ich weiß, das ich die Methode addConnection benutzen muss.
Code:
 for (int j = 1; j < splitLine.length; j++) {
                    graph.addConnection(splitLine[0], splitLine[j]);
                }
Nur wie realisiere ich in einem Stream das? Soweit ich es geschrieben habe, fügt er in die Map die Knoten ein. Wie schaffe ich es das er dann den jeweilgen Knoten nimmt und dazu dann die richtigen Verbindungen setzt?
 
Naja, Du ersetzt in erster Linie die for-Schleifen durch Streams. Wenn man das direkt macht, würde aus
Java:
        for (int i = 0; i < lines.size(); i++) {
            String[] splitLine = lines.get(i).split(" ");
            graph.addNode(splitLine[0]);
        }
z. B. erstmal
Java:
        lines.stream()
            .map(line -> line.split(" ")[0])
            .forEach(graph::addNode);

Das forEach ersetzt dabei Deine Schleife. Analog dazu kannst Du den Rest übersetzen. Da ich Dir nicht einfach die Lösung hinschreiben will, darfst Du das selbst versuchen. Noch ein Tipp: nachdem Du verschachtelte for-Schleifen hast, wird es bei einer direkten Übersetzung auch auf verschachteltes forEach hinauslaufen. Und alles, was Du brauchst, ist hier im Thread vorhanden.
 

Zurück
Oben