Bir akışı ters sırada sıralamak için Java8 lambda nasıl kullanılır?


181

Bir liste sıralamak için java lambda kullanıyorum.

nasıl tersine sıralayabilirim?

Bunu görene yazı ama Java'nın 8 lambda kullanmak istiyorum.

İşte bir hack olarak benim kod (* -1 kullandım)

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

"Ters sırada" ile ne demek istiyorsun? Eğer değiştirirseniz -1 * answerile answer, sipariş onunla ne olduğunu tersine değişecektir -1 * ....
dasblinkenlight

2
Dikkat! Kodunuzun Tüm kullanmak istediğiniz önerir forEachOrderedyerineforEach
Holger

Neden? açıklayabilir misin?
Elad Benda2

1
Bağlantıları takip edin. Basitçe söylersek, forEachOrderedadından da anlaşılacağı gibi , “değişiklik zamanına göre sıralanmış” siparişe dayanan belirli sayıda yeni dosyayı atlamak istediğinizde karşılaşılan karşılaşma sırasına önem vermektedir .
Holger

1
Biraz geç, sortskip→ (sırasız) forEachnasıl çalışması gerektiği konusundaki anlayışınızın doğru olduğunu ve bugünün JRE'lerinde bu şekilde çalışmanın gerçekten uygulandığını, ancak 2015'te, önceki yorumların yapıldığı zaman, gerçekten bir sorundu ( bu soruda okuyabileceğiniz gibi ).
Holger

Yanıtlar:


218

Bağlandığınız çözümü Java'da ArrayList <Uzun> azalan sırayla nasıl sıralayabilirim? lambda'ya sararak:

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

f2'ninLong.compare ikincisinin değil , ilk argümanı olduğuna dikkat edin , sonuç tersine çevrilecektir.


224
… VeyaComparator.comparingLong(File::lastModified).reversed()
Holger

3
@Holger dizesinin Akış ve sahip comparingLong(v->Long.valueOf(v)).reversed()derleme hata atar: java.lang.valueOf(java.lang.String) cannot be used on java.lang.valueOf(java.lang.Object). Neden?
Tiina

3
@Tiina: bkz. Comparator.reversed () yöntemi lambda kullanarak derlenmez . Bunun comparingLong(Long::valueOf).reversed()yerine deneyebilirsiniz . VeyaCollections.reverseOrder(comparingLong(v->Long.valueOf(v)))
Holger

@Holger bağlantı için teşekkürler. Ama Stuart "nedenini tam olarak bilmiyor". Bunun Tyerine her iki yöntemin başvurduğunu gördüğümde kafam karıştı Object, yani nesne türü kaybolmamalı. Ama aslında öyle. Bu konuda kafam karıştı.
Tiina

3
@Tiina: işe yaramayan hedef türün geri yayılımı . Zincirin ilk ifadesi bağımsız bir türe sahipse, Java 8'den önce olduğu gibi zincir üzerinden comparingLong(Long::valueOf).reversed()çalışır. işleri comparingLong((String v) -> Long.valueOf(v)).reversed()işleri. Ayrıca Stream.of("foo").mapToInt(s->s.length()).sum()çalışır, "foo"tek başına türü sağlarken Stream.of().mapToInt(s-> s.length()).sum()başarısız olur.
Holger

170

Akış öğeleriniz uygulanırsa Comparableçözüm daha basit hale gelir:

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

3
veya...stream().max(Comparator.naturalOrder())
Philippe

1
Bir koleksiyondaki tarihe göre karşılaştırma yapan en yeni öğe için.stream().max(Comparator.comparing(Clazz::getDate))
Marco Pelegrini

1
Elemanlar olmasa ne olacak Comparable. Collections.reverseböyle bir kısıtlama yoktur.
wilmol

63

kullanım

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

Sonra

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

3
Akarsular hakkında sordu, ama yine de cevabınızı seviyorum.
Tim Büthe

Bunu yapmanın "fonksiyonel" yolu değil ... yan etkileri var !!
Programcı

38

Bir yöntem referansı kullanabilirsiniz:

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

Yöntem referansına alternatif olarak lambda ifadesi kullanabilirsiniz, böylece karşılaştırma argümanı şöyle olur:

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

19

Alternatif yol paylaşımı:

ASC

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

AZALAN

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

4

Bu, Java 8 ve tersine çevrilmiş bir Karşılaştırıcı kullanılarak kolayca yapılabilir .

Sıralamak için basit bir karşılaştırıcı kullanarak sıralanmamış, sıralı ve ters sıralı görüntülemek ve daha sonra bu karşılaştırıcı ters sürümünü almak için üzerinde ters () çağıran bir dizinden dosya listesi oluşturduk.

Aşağıdaki koda bakın:

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 Koleksiyonlar ile dosya listesini sırala

Bir Dosya listesini sıralamak için Koleksiyonlar ve Karşılaştırıcı Java 8'i kullanma örneği.

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

Basit olarak, Karşılaştırıcı ve Koleksiyon'u kullanarak aşağıdaki gibi sıralayabilirsiniz: kullanarak JAVA 8'i kullanarak ters sırayla

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

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

0

Ters sıralama için sadece x1.compareTo (x2) yöntemini çağırmak için x1, x2 sırasını değiştirin.

Varsayılan sipariş

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

Ters sipariş

List<String> reverseSortedByName = citiesName.stream().sorted((s1,s2)->s2.compareTo(s1)).collect(Collectors.toList());
System.out.println("Reverse Sorted by Name : "+ reverseSortedByName );
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.