कस्टम छँटाई इस तरह से कि A, B से पहले आता है और B से पहले आता है


11

मेरे पास इस तरह के रंगों की सूची है:

गुलाबी, नीला, लाल, नीला, ग्रे, हरा, बैंगनी, काला ... आदि

List<String> listOfColors =  Arrays.asList("Pink", "Blue", "Red", "blue", "Grey", "green", "purple", "black");

कुछ मध्यवर्ती ऑपरेशन हैं जैसे कुछ फलों के रंगों को छानना, अब मुझे फ़िल्टर्ड परिणामों के साथ छोड़ दिया गया है जहाँ मैं चाहता हूँ कि उन्हें क्रम में क्रमबद्ध किया जाए:

नीला, काला, नीला, ग्रे, हरा, गुलाबी, बैंगनी, लाल

मैंने कोशिश की है :

List<String> collect = listOfColors.stream().sorted(String::compareToIgnoreCase)
        .collect(Collectors.toList());

यह अपेक्षा के अनुरूप काम नहीं करता है।

आउटपुट निम्नलिखित है:

काले, नीले, नीले, हरे, ग्रे, गुलाबी, बैंगनी, लाल

मुझे निम्नलिखित चाहिए:

नीला, काला, नीला, ग्रे, हरा, गुलाबी, बैंगनी, लाल


2
क्या ग्रे से पहले नीला और हरा से काला नहीं आना चाहिए?
रवींद्र रानवाला

3
aइससे पहले uकि परिणाम सही है
जेन्स

2
@ रविन्द्रनवाला, ब्लू की बी कैपिटल है लेकिन बैक की बी नहीं है।
विश्व रत्न

2
मैंने कोशिश की, लेकिन यह यह विशिष्ट आदेश नहीं देता है। यह [black, Blue, blue, green, Grey, Pink, purple, Red]@ चिरलीस-ऑनस्ट्राइक देता है-
रवींद्र रानवाला

2
यदि आप चाहते हैं कि कम आवरण से पहले पूंजी आवरण आ जाए, तो आवरण को अनदेखा करना आखिरी चीज है जो आप चाहते हैं।
तायपेमम

जवाबों:


8

मेरा समाधान Comparator.thenComparing()विधि का उपयोग करके दो चरणों में छंटाई का उपयोग करना है।

सबसे पहले, स्ट्रिंग्स की तुलना केवल पहले चरित्र की अनदेखी के मामले से करें। इसलिए समान चरित्र वाले समूह (चाहे कोई भी मामला हो) अब तक अनसोल्ड रहे। फिर दूसरे चरण में उन अनसुलझे उपसमूहों को क्रमबद्ध करने के लिए सामान्य वर्णमाला छँटाई को लागू करें।

List<String> listOfColors =  Arrays.asList("Pink", "Blue", "Red", "blue", "Grey", "green", "purple", "black");
Comparator<String> comparator = Comparator.comparing(s -> 
        Character.toLowerCase(s.charAt(0)));
listOfColors.sort(comparator.thenComparing(Comparator.naturalOrder()));
System.out.println(listOfColors);

शायद यह अभी भी अनुकूलित किया जा सकता है, लेकिन यह वांछित परिणाम देता है:

[Blue, black, blue, Grey, green, Pink, purple, Red]


की पठनीयता के लिए एक संपादन किया Comparator। लेकिन हां, यह केवल स्ट्रिंग के पहले चरित्र की तुलना करता है जिसके बारे में ओपी ने ज्यादा जोर नहीं दिया है।
नमन

8

आप अपने नियमों को परिभाषित करने के लिए RuleBasedCollator का उपयोग कर सकते हैं ।

कस्टम नियम का उदाहरण :

String rules = "< c,C < b,B";

उपर्युक्त नियम को डिकोड किया गया है क्योंकि अपरकेस और लोअरकेस Cदोनों को Bस्ट्रिंग्स की तुलना करते समय अपरकेस और लोअरकेस दोनों के सामने आना है ।

String customRules = "<A<a<B<b<C<c<D<d<E<e<F<f<G<g<H<h<I<i<J<j<K<k<L<l<M<m<N<n<O<o<P<p<Q<q<R<r<S<s<T<t<U<u<V<v<X<x<Y<y<Z<z";
RuleBasedCollator myRuleBasedCollator = new RuleBasedCollator(customRules);
Collections.sort(listOfColors,myRuleBasedCollator);
System.out.println(listOfColors);

आउटपुट:

[Blue, black, blue, Grey, green, Pink, purple, Red]

संपादित करें:customRules हाथ से लिखने के बजाय , आप इसे बनाने के लिए नीचे दिए गए कोड का उपयोग कर सकते हैं।

String a = IntStream.range('a', 'z' + 1).mapToObj(c -> Character.toString((char) c))
        .flatMap(ch -> Stream
            .of("<", ch.toUpperCase(), "<", ch)).collect(Collectors.joining(""));

2
निर्माण के String customRulesसाथ IntStreamIntStream.range('a', 'z' + 1) .mapToObj(Character::toString) .flatMap(ch -> Stream.of("<", ch.toUpperCase(), "<", ch)) .collect(Collectors.joining(""))
ऑटोमैटिज्म

@lczapski, किसी तरह .mapToObj(Character::toString)हल नहीं होगा, मुझे लगता है कि आपको उपयोग करने की आवश्यकता है.mapToObj(c -> Character.toString((char) c))
विश्व रत्न

mapToObj(Character::toString)केवल जावा 11 या नए में काम करता है।
होल्गर

@ होल्गर ठीक है, मैंने अपने सिस्टम (JDK-8) पर कोशिश की और mapToObj(Character::toString)हल नहीं हो रहा था, लेकिन मुझे यह विचार पसंद आया इसलिए मैंने कास्टिंग करना पसंद किया.mapToObj(c -> Character.toString((char) c))
विश्व रत्न

3
मैं पसंद करूँगाIntStream.rangeClosed('a', 'z').flatMap(c -> IntStream.of(c,Character.toUpperCase(c))) .mapToObj(c -> Character.toString((char)c)) .collect(Collectors.joining("<", "<", ""));
Holger

0

आपको एक ऐसी विधि की आवश्यकता है जो पहले प्रत्येक पत्र पर एक मामले की असंवेदनशील तुलना करती है, फिर यदि कोई मैच प्रत्येक पत्र पर एक केस की तुलनात्मक तुलना करता है:

public static int compare(String s1, String s2)
{
    int len, i;
    if (s1.length()<s2.length()) {
        len = s1.length();
    } else {
        len = s2.length();
    }
    for (i=0;i<len;i++) {
        if (Character.toUpperCase(s1.charAt(i)) < Character.toUpperCase(s2.charAt(i))) {
            return -1;
        } else if (Character.toUpperCase(s1.charAt(i)) > Character.toUpperCase(s2.charAt(i))) {
            return 1;
        } else if (s1.charAt(i) < s2.charAt(i)) {
            return -1;
        } else if (s1.charAt(i) > s2.charAt(i)) {
            return 1;
        }
    }
    if (s1.length() < s2.length()) {
        return -1;
    } else if (s1.length() > s2.length()) {
        return 1;
    } else {
        return 0;
    }
}

फिर आप इस विधि को पास कर सकते हैं Stream.sorted

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.