Java8 람다를 사용하여 스트림을 역순으로 정렬하는 방법은 무엇입니까?


181

Java 람다를 사용하여 목록을 정렬하고 있습니다.

역순으로 정렬하려면 어떻게해야합니까?

게시물 을 보았지만 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

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 String of String, 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

링크에 대한 @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()실패합니다.
Holger

170

스트림 요소가 구현 Comparable되면 솔루션이 더 간단 해집니다.

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

3
또는...stream().max(Comparator.naturalOrder())
Philippe

1
날짜별로 비교 한 컬렉션의 최신 요소.stream().max(Comparator.comparing(Clazz::getDate))
Marco Pelegrini

1
어떤 요소가없는 경우 Comparable. Collections.reverse그러한 제한이 없습니다.
윌몰

63

사용하다

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

그때

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

3
글쎄, 그는 스트림에 대해 물었지만 그럼에도 불구하고 나는 당신의 대답을 좋아합니다.
Tim Büthe

이것은 "기능적인"방법이 아닙니다. 그것은 부작용이 있습니다 !!
프로그래머

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());

DESC

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

4

이것은 Java 8과 역 Comparator를 사용하여 쉽게 수행 할 수 있습니다 .

디렉토리에서 파일 목록을 만들었습니다.이 목록은 정렬을 위해 간단한 Comparator를 사용하여 정렬되지 않은, 정렬 및 역 정렬 된 다음 반전 된 버전을 얻기 위해 reversed ()를 호출합니다.

아래 코드를 참조하십시오 :

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 Collections로 파일 목록 정렬

Collections 및 Comparator 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.