0

フィールドを持つ非常に単純な Java BeanWatchedFileがありfileNameます。

fj.data.Listオブジェクトの をソートしたいのですが、リストのメソッドのWatchedFileを定義するのに苦労しています。これは私が思いついたものです:fj.Ordsort()

protected List<WatchedFile> getWatchedFileList(String path) throws IOException {
    List<File> files = List.list(new File(path).listFiles());
    return files
            .map((file) -> new WatchedFile(file.getName(), false, file.length()))
            .sort(Ord.ord(new F<WatchedFile, F<WatchedFile, Ordering>>()
            {
                @Override
                public F<WatchedFile, Ordering> f(final WatchedFile watchedFile1)
                {
                    return new F<WatchedFile, Ordering>()
                    {
                        @Override
                        public Ordering f(final WatchedFile watchedFile2)
                        {
                            int compareResult = watchedFile1.fileName.compareTo(watchedFile2.fileName);
                            return (compareResult < 0 ? Ordering.LT :
                                    (compareResult > 0 ? Ordering.GT : Ordering.EQ));
                        }
                    };
                }
            }));
}

これは醜いです!オブジェクトをインスタンス化するより良い方法があると確信していOrdます...おそらくJava 8の魔法を利用していますか?

4

1 に答える 1

2
protected List<WatchedFile> getWatchedFileList(String path) throws IOException {
    List<File> files = Arrays.asList(new File(path).listFiles());
    return files.stream()
        .map(file -> new WatchedFile(file.getName(), false, file.length()))
        .sorted((wf1, wf2)->wf1.fileName.compareTo(wf2.fileName))
        .collect(Collectors.toList());
}

public String getFileName()クラスにメソッドを含めることをお勧めしますWatchedFile。その場合、次のように簡単に言えます。

protected List<WatchedFile> getWatchedFileList(String path) throws IOException {
    List<File> files = Arrays.asList(new File(path).listFiles());
    return files.stream()
        .map(file -> new WatchedFile(file.getName(), false, file.length()))
        .sorted(Comparator.comparing(WatchedFile::getFileName))
        .collect(Collectors.toList());
}

また、ディレクトリ エントリを取得するために NIO2 を使用すると、次のようになります。

protected List<WatchedFile> getWatchedFileList(String path) throws IOException {
    try {
        return Files.list(Paths.get(path))
            .map(p -> new WatchedFile(p.toString(), false, fileSize(p)))
            .sorted(Comparator.comparing(WatchedFile::getFileName))
            .collect(Collectors.toList());
    } catch(UncheckedIOException ex) { throw ex.getCause(); }
}
private long fileSize(Path path) {
    try { return Files.size(path); }
    catch (IOException ex) { throw new UncheckedIOException(ex); }
}

「functional-java」API 内に留まりたい場合、ソリューションは次のようになります。

protected List<WatchedFile> getWatchedFileList(String path) throws IOException {
    List<File> files = List.list(new File(path).listFiles());
    return files
        .map(file -> new WatchedFile(file.getName(), false, file.length()))
        .sort(Ord.stringOrd.comap(wf -> wf.fileName));
}

String重要な点は、 s が比較される方法を再実装する必要がない (すべきではない) ということです。代わりに、比較するプロパティ値を取得する関数を指定します。Comparator.comparing2 番目のコード例で使用されているJava 8 ファクトリ メソッドと比較してください。

于 2014-09-15T10:41:04.733 に答える