Der Vorteil einer Map, kann daraus bestehen, dass dynamisch auf verschiedene Datentypen reagiert werden kann.
[SPOILER]```import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
public class CSVReader {
public static Iterator<Map<String, String>> getIterator() {
final Scanner scanner = new Scanner(System.in);
if (scanner.hasNextLine()) {
final String[] columns = scanner.nextLine().split(" ");
return new Iterator<Map<String, String>>() {
@Override
public boolean hasNext() {
return scanner.hasNextLine();
}
@Override
public Map<String, String> next() {
String[] line = scanner.nextLine().split(" ");
Map<String, String> entry = new HashMap<>();
for (int i = 0; i < columns.length; i++) {
entry.put(columns**, line**);
}
return entry;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
} else {
return new Iterator<Map<String, String>>() {
@Override
public boolean hasNext() {
return false;
}
@Override
public Map<String, String> next() {
throw new NullPointerException();
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
}
public static String toJson(Iterator<Map<String, String>> csvIterator) {
StringBuilder builder = new StringBuilder("{\"result\":[
“);
while (csvIterator.hasNext()) {
Map<String, String> entry = csvIterator.next();
builder.append(”{");
boolean printComma = false;
for (String key : entry.keySet()) {
if (printComma) {
builder.append(", “);
}
printComma = true;
builder.append(String.format(”"%s":"%s"", key, entry.get(key)));
}
builder.append("}");
if (csvIterator.hasNext()) {
builder.append(",");
builder.append("
“);
}
}
return builder.append(”
]}").toString();
}
public static Iterator<Map<String, String>> filter(final String key, final String value, final Iterator<Map<String, String>> it) {
return new Iterator<Map<String, String>>() {
private Map<String, String> current = null;
@Override
public boolean hasNext() {
while (current == null && it.hasNext()) {
current = it.next();
if (current.get(key).equals(value)) {
return true;
} else {
current = null;
}
}
return current != null && current.get(key).equals(value);
}
@Override
public Map<String, String> next() {
if (current != null) {
Map<String, String> result = current;
current = null;
return result;
} else {
throw new NullPointerException();
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public static Iterator<Map<String, String>> project(final String[] keys, final Iterator<Map<String, String>> it) {
return new Iterator<Map<String, String>>() {
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public Map<String, String> next() {
Map<String, String> entry = it.next();
Map<String, String> result = new HashMap<>();
for (String key : keys) {
result.put(key, entry.get(key));
}
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public static void main(String[] args) throws FileNotFoundException {
Iterator<Map<String, String>> it = getIterator();
if (args.length == 1) {
Scanner scanner = new Scanner(new File(args[0]));
while (scanner.hasNextLine()) {
String[] line = scanner.nextLine().split(" ");
switch (line[0]) {
case "filter":
it = filter(line[1], line[2], it);
break;
case "projection":
String[] pros = new String[line.length - 1];
System.arraycopy(line, 1, pros, 0, pros.length);
it = project(pros, it);
break;
}
}
}
String result = toJson(it);
System.out.println(result);
}
}
Eine Implementierung mit der man Einträge filtern, auf weniger Spalten projezieren und als JSon ausgeben kann.
Beispiel des TO:
Input
[SPOILER]
Ort Bundesland Bürgermeister
Berlin Berlin Wowi
Hamburg Hamburg Scholz
München Bayern Horst
Hannover Niedersachsen Horstine
[/SPOILER]
Rezept
filter Ort Berlin
projection Bürgermeister Bundesland
Aufruf
cat test.dat | java CSVReader test.recipe
Ausgabe
{“result”:[
{“Bürgermeister”:“Wowi”, “Bundesland”:“Berlin”}
]}
Fussball-Beispiel
Input
[SPOILER]
Saison Meister
1998/99 FC Bayern München
99/2000 FC Bayern München
2000/01 FC Bayern München
2001/02 Borussia Dortmund
2002/03 FC Bayern München
2003/04 Werder Bremen
2004/05 FC Bayern München
2005/06 FC Bayern München
2006/07 VfB Stuttgart
2007/08 FC Bayern München
2008/09 VfL Wolfsburg
2009/10 FC Bayern München
2010/11 Borussia Dortmund
2011/12 Borussia Dortmund
2012/13 FC Bayern München
[/SPOILER]
Rezept
filter Meister FC Bayern München
projection Saison
Aufruf
cat fussball.dat | java CSVReader fussball.recipe
Ausgabe
{“result”:[
{“Saison”:“1998/99”},
{“Saison”:“99/2000”},
{“Saison”:“2000/01”},
{“Saison”:“2002/03”},
{“Saison”:“2004/05”},
{“Saison”:“2005/06”},
{“Saison”:“2007/08”},
{“Saison”:“2009/10”},
{“Saison”:“2012/13”}
]}
Die Dinge, also filter, projektion etc. die in recipe definiert werden, kann man auch gut in eine GUI verpacken. Damit kann man dann nahezu beliebige CSV Dateien auswählen und analysieren ohne extra Klassen zu erstellen und kompilieren zu müssen.
Das kann man schon praktisch finden?