Java8ラムダを使用してストリームを逆順にソートする方法は?


181

リストをソートするためにjava lambdaを使用しています。

逆に並べ替えるにはどうすればよいですか?

この投稿を見ましたが、Java 8ラムダを使用したいと思います。

これがハックとしての私のコードです(私は* -1を使用しました)。

Arrays.asList(files).stream()
    .filter(file -> isNameLikeBaseLine(file, baseLineFile.getName()))
    .sorted(new Comparator<File>() {
        public int compare(File o1, File o2) {
            int answer;
            if (o1.lastModified() == o2.lastModified()) {
                answer = 0;
            } else if (o1.lastModified() > o2.lastModified()) {
                answer = 1;
            } else {
                answer = -1;
            }
            return -1 * answer;
        }
    })
    .skip(numOfNewestToLeave)
    .forEach(item -> item.delete());

「逆順」とはどういう意味ですか?で置き換える-1 * answeranswer、順序はと逆になり-1 * ...ます。
dasblinkenlight 2015

2
注意してください!すべてのコードは、forEachOrdered代わりに使用したいことを示唆していますforEach
Holger

何故ですか?説明できますか?
Elad Benda2

1
リンクをたどってください。簡単に言うと、forEachOrderedその名前が示すように、「変更時刻でソートされた」順序に依存する特定の数の最新ファイルをスキップしたいので、関連する遭遇順序に注意します。
Holger、

1
ビットが遅れて、私はどのようにのご理解と認めたいsortskip→(順不同)がforEach動作するはず、正しく、それは、以前のコメントがなされたとき、確かに今日のJREでこのように動作するように実装されますが、バック2015になっていること確かに問題でした(この質問でお読みになるかもしれません)。
Holger

回答:


218

JavaでArrayList <Long>を降順に並べ替える方法でリンクしたソリューションを適応できますか?ラムダで包むことによって:

.sorted((f1, f2) -> Long.compare(f2.lastModified(), f1.lastModified())

そのノートf2はの最初の引数でLong.compareはなく、第二、その結果は逆になります。


224
…またはComparator.comparingLong(File::lastModified).reversed()
Holger

3
文字列の@Holgerストリーム、およびcomparingLong(v->Long.valueOf(v)).reversed()コンパイルエラーがスローされます:java.lang.valueOf(java.lang.String) cannot be used on java.lang.valueOf(java.lang.Object)。どうして?
Tiina

3
@Tiina:Comparator.reversed()がlambdaを使用してコンパイルされないを参照してください。comparingLong(Long::valueOf).reversed()代わりに試すことができます。またはCollections.reverseOrder(comparingLong(v->Long.valueOf(v)))
Holger

リンクをありがとう@ホルガー。しかし、スチュアートは「理由は完全にはわかりません」。両方のメソッドがのT代わりに参照するのを見たとき、私は混乱しましたObject。つまり、オブジェクトタイプが失われるべきではありません。しかし、実際にはそうです。それが私が混乱しているものです。
Tiina

3
@Tiina:機能しないターゲットタイプの逆伝播です。チェーンの最初の式がスタンドアロン型の場合、Java 8以前と同じようにチェーン全体で機能します。コンパレーターの例でわかるように、メソッド参照を使用して、つまりcomparingLong(Long::valueOf).reversed()、明示的に型指定されたラムダ式と同様に機能します。動作しcomparingLong((String v) -> Long.valueOf(v)).reversed()ます。またStream.of("foo").mapToInt(s->s.length()).sum()として、働く"foo"一方で、スタンドアローン型の提供Stream.of().mapToInt(s-> s.length()).sum()失敗を。
ホルガー2017年

170

ストリーム要素が実装するComparable場合、ソリューションはより簡単になります:

 ...stream()
 .sorted(Comparator.reverseOrder())

3
または...stream().max(Comparator.naturalOrder())
フィリップ

1
日付で比較するコレクションの最新の要素について.stream().max(Comparator.comparing(Clazz::getDate))
Marco Pelegrini

1
どのような要素ではない場合ComparableCollections.reverseそのような制限はありません。
wilmol

63

使用する

Comparator<File> comparator = Comparator.comparing(File::lastModified); 
Collections.sort(list, comparator.reversed());

その後

.forEach(item -> item.delete());

3
さて、彼はストリームについて尋ねましたが、それでも私はあなたの答えが好きです。
TimBüthe16年

これは「機能的な」方法ではありません...副作用があります!!
プログラマー、

38

メソッド参照を使用できます。

import static java.util.Comparator.*;
import static java.util.stream.Collectors.*;

Arrays.asList(files).stream()
    .filter(file -> isNameLikeBaseLine(file, baseLineFile.getName()))
    .sorted(comparing(File::lastModified).reversed())
    .skip(numOfNewestToLeave)
    .forEach(item -> item.delete());

メソッド参照の代わりにラムダ式を使用できるため、比較の引数は次のようになります。

.sorted(comparing(file -> file.lastModified()).reversed());

19

別の方法で共有:

ASC

List<Animal> animals = this.service.findAll();
animals = animals.stream().sorted(Comparator.comparing(Animal::getName)).collect(Collectors.toList());

説明

List<Animal> animals = this.service.findAll();
animals = animals.stream().sorted(Comparator.comparing(Animal::getName).reversed()).collect(Collectors.toList());

4

これは、Java 8と反転コンパレータの使用を使用して簡単に行うことができます。

ディレクトリからファイルのリストを作成しました。並べ替えに単純なコンパレータを使用して、並べ替えなし、並べ替え、逆並べ替えを表示し、その上でreverse()を呼び出して、そのコンパレータの逆バージョンを取得します。

以下のコードを参照してください。

package test;

import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

public class SortTest {
    public static void main(String... args) {
        File directory = new File("C:/Media");
        File[] files = directory.listFiles();
        List<File> filesList = Arrays.asList(files);

        Comparator<File> comparator = Comparator.comparingLong(File::lastModified);
        Comparator<File> reverseComparator = comparator.reversed();

        List<File> forwardOrder = filesList.stream().sorted(comparator).collect(Collectors.toList());
        List<File> reverseOrder = filesList.stream().sorted(reverseComparator).collect(Collectors.toList());

        System.out.println("*** Unsorted ***");
        filesList.forEach(SortTest::processFile);

        System.out.println("*** Sort ***");
        forwardOrder.forEach(SortTest::processFile);

        System.out.println("*** Reverse Sort ***");
        reverseOrder.forEach(SortTest::processFile);
    }

    private static void processFile(File file) {
        try {
            if (file.isFile()) {
                System.out.println(file.getCanonicalPath() + " - " + new Date(file.lastModified()));
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

3

Java 8コレクションでファイルリストをソートする

コレクションとコンパレータJava 8を使用してファイルリストをソートする方法の例。

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ShortFile {

    public static void main(String[] args) {
        List<File> fileList = new ArrayList<>();
        fileList.add(new File("infoSE-201904270100.txt"));
        fileList.add(new File("infoSE-201904280301.txt"));
        fileList.add(new File("infoSE-201904280101.txt"));
        fileList.add(new File("infoSE-201904270101.txt"));

        fileList.forEach(x -> System.out.println(x.getName()));
        Collections.sort(fileList, Comparator.comparing(File::getName).reversed());
        System.out.println("===========================================");
        fileList.forEach(x -> System.out.println(x.getName()));
    }
}

1

シンプルで、あなたは以下のように並べ替えることができますコンパレータおよびコレクションを使用して反転 JAVAを使用して順序8

import java.util.Comparator;;
import java.util.stream.Collectors;

Arrays.asList(files).stream()
    .sorted(Comparator.comparing(File::getLastModified).reversed())
    .collect(Collectors.toList());

0

逆ソートの場合、x1.compareTo(x2)メソッドを呼び出すためにx1、x2の順序を変更するだけで、結果は互いに逆になります

デフォルトの順序

List<String> sortedByName = citiesName.stream().sorted((s1,s2)->s1.compareTo(s2)).collect(Collectors.toList());
System.out.println("Sorted by Name : "+ sortedByName);

逆順

List<String> reverseSortedByName = citiesName.stream().sorted((s1,s2)->s2.compareTo(s1)).collect(Collectors.toList());
System.out.println("Reverse Sorted by Name : "+ reverseSortedByName );
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.