रिवर्स ऑर्डर में स्ट्रीम को सॉर्ट करने के लिए Java8 लैम्ब्डा का उपयोग कैसे करें?


180

मैं एक सूची को सॉर्ट करने के लिए जावा लैम्ब्डा का उपयोग कर रहा हूं।

मैं इसे उल्टे तरीके से कैसे छाँट सकता हूँ?

मैंने इस पोस्ट को देखा , लेकिन मैं जावा 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 * answerसाथ प्रतिस्थापित करते हैं answer, तो यह क्या था के साथ क्रम उलट जाएगा -1 * ...
dasblinkenlight

2
सावधान रहें! आपके सभी कोड यह सुझाव देते हैं कि आप forEachOrderedforEach
Holger

ऐसा क्यों है? क्या तुम समझा सकते हो?
एलाड बेंडा 2

1
लिंक का पालन करें। सीधे शब्दों में कहा जाए, forEachOrderedजैसा कि नाम से ही पता चलता है कि एनकाउंटर ऑर्डर की परवाह है, जो प्रासंगिक है क्योंकि आप कुछ निश्चित नई फाइलों को छोड़ना चाहते हैं, जो "संशोधन के समय द्वारा क्रमबद्ध" क्रम पर निर्भर करती हैं ।
होल्गर

1
एक देर से काटा, मैं स्वीकार करना चाहते हैं उनकी अपनी समझ कैसे sortskip→ (अव्यवस्थित) forEachकाम करना चाहिए, यह है कि यह वास्तव में आज के JREs में इस तरह से काम करने के लिए लागू किया गया है सही है और है, लेकिन 2015, में वापस आ गया जब पिछली टिप्पणी किए गए थे, यह वास्तव में एक मुद्दा था (जैसा कि आप इस प्रश्न में पढ़ सकते हैं )।
होल्गर

जवाबों:


218

आप घटते क्रम में जावा में ArrayList <Long> को सॉर्ट करने के लिए आपके द्वारा जुड़े समाधान को अनुकूलित कर सकते हैं ? एक मेमने में लपेटकर:

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

ध्यान दें कि f2 का पहला तर्क है Long.compare, दूसरा नहीं, इसलिए इसका परिणाम उल्टा होगा।


224
… याComparator.comparingLong(File::lastModified).reversed()
होल्गर

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
@ टीइना: कम्पैरिबेटर देखें। () लैम्बडा के उपयोग से संकलन नहीं करता है । आप comparingLong(Long::valueOf).reversed()इसके बजाय कोशिश कर सकते हैं । याCollections.reverseOrder(comparingLong(v->Long.valueOf(v)))
होल्गर

@ होलगर लिंक के लिए धन्यवाद। लेकिन स्टुअर्ट "पूरी तरह से निश्चित नहीं है कि क्यों"। जब मैंने दोनों तरीकों को संदर्भित Tकरने के बजाय देखा तो मैं उलझन में था Object, जिसका अर्थ है कि ऑब्जेक्ट प्रकार को खोना नहीं चाहिए। लेकिन वास्तव में यह है। यही मैं उलझन में हूं।
Tiina

3
@ टीइना: यह लक्ष्य प्रकार का बैक-प्रचार है जो काम नहीं करता है। यदि आपकी श्रृंखला की प्रारंभिक अभिव्यक्ति में स्टैंड-अलोन प्रकार है, तो यह चेन के माध्यम से काम करता है जैसे कि यह जावा 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()है।
होल्गर

170

यदि आपकी धारा तत्व लागू होते हैं Comparableतो समाधान सरल हो जाता है:

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

3
या...stream().max(Comparator.naturalOrder())
फिलिप

1
दिनांक द्वारा तुलना करने वाले संग्रह में सबसे हाल के तत्व के लिए.stream().max(Comparator.comparing(Clazz::getDate))
मार्को पेलेग्रीनी

1
अगर तत्व नहीं हैं तो क्या होगा ComparableCollections.reverseइस तरह का प्रतिबंध नहीं है।
विल्मोल

63

उपयोग

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

फिर

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

3
खैर, उन्होंने धाराओं के बारे में पूछा, लेकिन मुझे आपका जवाब पसंद है।
टिम ब्यूटे

यह ऐसा करने का "कार्यात्मक" तरीका नहीं है ... यह पक्ष को प्रभावित करता है !!
प्रोग्रामर

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

वैकल्पिक तरीका साझा करना:

एएससी

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

यह आसानी से जावा 8 का उपयोग करके और एक उलट तुलना का उपयोग किया जा सकता है ।

मैंने एक डायरेक्टरी से फाइलों की एक सूची बनाई है, जिसे मैं सॉर्ट किया गया, सॉर्ट किया गया और रिवर्स सॉर्ट किया गया जो सॉर्ट करने के लिए एक सिंपल कम्पैक्टर का उपयोग कर रहा था और फिर उस कंपैक्टर का उल्टा वर्जन प्राप्त करने के लिए उस पर उल्टा () कॉल कर रहा था।

नीचे देखें कोड:

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 कलेक्शन के साथ फाइल लिस्ट को सॉर्ट करें

उदाहरण के लिए संग्रह और तुलनित्र जावा 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

सरल में, तुलनाकारी और संग्रह का उपयोग कर आप नीचे दिए गए की तरह में सॉर्ट कर सकते हैं उलट क्रम जावा 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 का ऑर्डर बदलें। X.compareTo (x2) विधि को कॉल करने के लिए 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 );
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.