Bitte helft mir bei einem einfachem Beispiel, ich möchte ein Verzeichnis auflisten:
import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
public class ListDirs {
public static void main(String[] args) {
File d = new File("a Directory");
File[] files = d.listFiles();
Arrays.stream(files)
.filter(File::isDirectory)
.sorted(Comparator.comparing(File::lastModified).reversed())
.limit(12)
.map(File::getName)
.map(s -> s.substring(0, s.lastIndexOf('-') - 5))
.forEach(System.out::println);
}
}
Arrays.stream(files) files könnte null sein… .limit(12) was passiert bei weniger als 12? s -> s.substring(0, s.lastIndexOf('-') - 5) lässt sich das vereinfachen?
Vielen Dank!
Edit: Könnte das ein Kompromiss sein?:
import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
public class ListDirs {
public static void main(String[] args) {
@SuppressWarnings("SpellCheckingInspection")
File d = new File("abc");
File[] files = d.listFiles();
assert files != null;
Arrays.stream(files)
.filter(File::isDirectory)
.sorted(Comparator.comparing(File::lastModified).reversed())
.limit(12)
.map(File::getName)
.map(s -> s.substring(0, s.lastIndexOf('-') - 5)) // negative value?
.forEach(System.out::println);
}
}
Ich würde die Method getSub() sprechender machen. Was tut diese Methode?
Auch den Parameter lio würde ich sprechend umformulieren.
Ich würde vermutlich auch als Rückgabewert auf Optional setzen. Das macht die Signature der Methode klarer.
Das Limit würde ich einfach vor das letzte forEach setzen.
Jetzt gefällt mir es und die Klasse ist auch grün geworden:
import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.function.Predicate;
public class ListDirs {
public static void main(String[] args) {
@SuppressWarnings("SpellCheckingInspection")
File d = new File("...");
File[] files = d.listFiles();
assert files != null;
Arrays.stream(files)
.filter(File::isDirectory)
.sorted(Comparator.comparing(File::lastModified).reversed())
.map(File::getName)
.filter(((Predicate<String>) s -> s.contains("-")).and(s -> s.lastIndexOf('-') - 5 > 0))
.map(s -> s.substring(0, s.lastIndexOf('-') - 5))
.limit(12)
.forEach(System.out::println);
}
}
@Landei Eine Frage zur Theorie… Ist .limit( ) vor- oder nachgreifend? Also es gilt nicht für den gesamten Stream oder? Nur für alles danach. Dann sollte es doch eigentlich so früh wie möglich platziert werden.
Es beschränkt die Anzahl Elemente an der Stelle, wo es aufgerufen wird (ist aber trotzdem so lazy wie möglich). Aber ganz ehrlich, du kannst so eine Sache schneller ausprobieren, als hier eine Frage zu stellen:
System.out.println(Stream.of(1,2,3,4,5,6).limit(2).filter(x -> x % 2 == 0).collect(Collectors.toList()));
// [2]
System.out.println(Stream.of(1,2,3,4,5,6).filter(x -> x % 2 == 0).limit(2).collect(Collectors.toList()));
// [2, 4]
Sehe ich das denn richtig, wenn ich das limit eine Zeile weiter oben geschrieben hätte (also zwischen filter und map), dass dann intern genau ein substring-Aufruf eingespart würde?