মান অনুসারে একটি মানচিত্র <কী, মান> বাছাই করুন


1634

আমি জাভাতে তুলনামূলকভাবে নতুন এবং প্রায়শই দেখতে পাই যে Map<Key, Value>মানগুলি অনুসারে আমার সাজানো দরকার ।

যেহেতু মানগুলি অনন্য নয়, তাই আমি নিজেকে এটিকে রূপান্তরিত করতে keySetএবং অ্যারের সাথে একটি কাস্টম তুলনাকারীরarray মাধ্যমে বাছাই করে যা কীটির সাথে সম্পর্কিত মান অনুসারে সাজায়।

কোন সহজ উপায় আছে?


24
মানচিত্রটি বাছাই করার উদ্দেশ্যে নয়, দ্রুত অ্যাক্সেস করা হয়। বস্তুর সমান মান মানচিত্রের সীমাবদ্ধতা ভঙ্গ করে। এন্ট্রি সেটটি পছন্দ করুন List<Map.Entry<...>> list =new LinkedList(map.entrySet())এবং Collections.sort ....এটি সেভাবে ব্যবহার করুন।
হ্যানস

1
যখন আমরা জাভাতে একটি কাউন্টার ব্যবহার করার চেষ্টা করি (মানচিত্র <অবজেক্ট, পূর্ণসংখ্যক) this সংঘটন সংখ্যার অনুসারে বাছাই করা তখন একটি সাধারণ ক্রিয়াকলাপ হবে। পাইথনের মতো ভাষার কাউন্টার ডেটা স্ট্রাকচার একটি বিল্ট ইন রয়েছে। জাভাতে প্রয়োগের বিকল্প পদ্ধতির জন্য, এখানে একটি উদাহরণ রয়েছে
ডেমোঙ্গোলেম

6
বাছাই করা মানচিত্রের জন্য প্রচুর ব্যবহারের কেস রয়েছে, এজন্য আপনার কাছে জেডিতে ট্রিম্যাপ এবং সমকালীন স্কিপলিস্টম্যাপ রয়েছে।
alobodzk


1
টিআরম্যাপ এবং কনক্র্যান্টস্কিপলিস্টম্যাপ কী অনুসারে বাছাই করুন। প্রশ্নটি মান অনুসারে বাছাই করার বিষয়ে।
পিটার

উত্তর:


897

এখানে একটি জেনেরিক-বান্ধব সংস্করণ রয়েছে:

public class MapUtil {
    public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) {
        List<Entry<K, V>> list = new ArrayList<>(map.entrySet());
        list.sort(Entry.comparingByValue());

        Map<K, V> result = new LinkedHashMap<>();
        for (Entry<K, V> entry : list) {
            result.put(entry.getKey(), entry.getValue());
        }

        return result;
    }
}

10
খুশি এই সাহায্য করে। জন, লিঙ্কডহ্যাশম্যাপটি সমাধানের পক্ষে গুরুত্বপূর্ণ কারণ এটি অনুমানযোগ্য পুনরাবৃত্তির ক্রম সরবরাহ করে।
কার্টর পৃষ্ঠা

3
@ buzz3791 সত্য। এটি কোনও বাছাই অ্যালগরিদমের ক্ষেত্রে হতে চলেছে। সাজানোর সময় কোনও কাঠামোর নোডের মান পরিবর্তন করুন অনির্দেশ্য (এবং প্রায় সবসময় খারাপ) ফলাফল তৈরি করে।
কার্টার পৃষ্ঠা

3
@ শেগোরথ আমি এন্ড্রয়েডে চেষ্টা করেছিলাম এবং এটিও কার্যকর হয়। আপনি জাভা 6 সংস্করণ ব্যবহার করছেন তা বিবেচনা করে এটি প্ল্যাটফর্ম নির্দিষ্ট সমস্যা নয়। আপনি কি আপনার মান অবজেক্টে তুলনামূলকভাবে সঠিকভাবে প্রয়োগ করেছেন ?
সায়ানকোডার

6
এর forEachOrderedপরিবর্তে জাভা 8 সংস্করণ ব্যবহার করা উচিত নয় forEach, যেহেতু ডকসগুলিতে forEachবলা হয়েছে: "এই অপারেশনের আচরণটি স্পষ্টতই নিরপেক্ষবাদী?"
ছিনতাই

1
এটি সম্পূর্ণরূপে ছিঁড়ে গেছে, তবে মন্তব্যে @ কার্টারপেজকে জমা দেওয়া হয়েছে (এটি যাইহোক কোনও ওপেন সোর্স প্রকল্পে হবে)। অনেক ধন্যবাদ.
নাথান বিচ

419

গুরুত্বপূর্ণ তথ্য:

এই কোডটি একাধিক উপায়ে ভঙ্গ করতে পারে। যদি আপনি প্রদত্ত কোডটি ব্যবহার করতে চান, তবে এর প্রভাব সম্পর্কে সচেতন হওয়ার জন্য মন্তব্যগুলি অবশ্যই পড়তে ভুলবেন না। উদাহরণস্বরূপ, মানগুলি কী দ্বারা আর পুনরুদ্ধার করা যাবে না। ( getসর্বদা ফিরে আসে null।)


পূর্ববর্তী সমস্তগুলির তুলনায় এটি অনেক সহজ বলে মনে হচ্ছে। নিম্নলিখিত হিসাবে একটি ট্রিম্যাপ ব্যবহার করুন:

public class Testing {
    public static void main(String[] args) {
        HashMap<String, Double> map = new HashMap<String, Double>();
        ValueComparator bvc = new ValueComparator(map);
        TreeMap<String, Double> sorted_map = new TreeMap<String, Double>(bvc);

        map.put("A", 99.5);
        map.put("B", 67.4);
        map.put("C", 67.4);
        map.put("D", 67.3);

        System.out.println("unsorted map: " + map);
        sorted_map.putAll(map);
        System.out.println("results: " + sorted_map);
    }
}

class ValueComparator implements Comparator<String> {
    Map<String, Double> base;

    public ValueComparator(Map<String, Double> base) {
        this.base = base;
    }

    // Note: this comparator imposes orderings that are inconsistent with
    // equals.
    public int compare(String a, String b) {
        if (base.get(a) >= base.get(b)) {
            return -1;
        } else {
            return 1;
        } // returning 0 would merge keys
    }
}

আউটপুট:

unsorted map: {D=67.3, A=99.5, B=67.4, C=67.4}
results: {D=67.3, B=67.4, C=67.4, A=99.5}

18
আর কোনও নয় ( স্ট্যাকওভারফ্লো . com / প্রশ্নগুলি ১০৯৯৩৮৩/২ )। এছাড়াও, কেন সেখানে ডাবল অভিনেতা ছিল? এটা ঠিক করা উচিত নয় return ((Comparable)base.get(a).compareTo(((Comparable)base.get(b)))?
স্টিফেন

12
@ স্টেফেন: না। এক্ষেত্রে মান অনুসারে সমান কীগুলি বাদ দেওয়া হয় (রেফারেন্সের সাথে সমান এবং তুলনার মধ্যে পার্থক্য)। অতিরিক্তভাবে: এমনকি এই map.put("A","1d");map.put("B","1d");map.put("C",67d);map.put("D",99.5d);
কোডটিতে

43
গাছের মানচিত্রের জন্য যে তুলনা করা হয় তা সমান (যেমন বাছাই ম্যাপ জাভাদক্স দেখুন) এর সাথে সামঞ্জস্যপূর্ণ নয়। এর অর্থ গাছের মানচিত্র থেকে আইটেমগুলি অবসর নেওয়ার কাজ করবে না। sort_map.get ("A") নਾਲ ফিরে আসবে। তার মানে গাছের এই মানচিত্রটি ভেঙে গেছে।
mR_fr0g

87
কেবলমাত্র যদি এটি লোকদের কাছে পরিষ্কার থাকে না: আপনার যদি একই মানটিতে একাধিক কী ম্যাপিং থাকে তবে এই সমাধানটি আপনি যা চান তা করতে পারে না - এই কীগুলির মধ্যে একটিরই সাজানো ফলাফলে উপস্থিত হবে।
ম্যাক্সি-বি

63
লুই ওয়াসারম্যান (হ্যাঁ, গুগু পেয়ারা ছেলেদের মধ্যে একটি) আসলে এই উত্তরটিকে কিছুটা অপছন্দ করে: "এটি এমনকি মজার দিকে তাকিয়ে দেখলে এটি বেশ কয়েকটি বিভ্রান্তিকর উপায়ে ভেঙে যায় If একই মানটিতে মানচিত্রটি ভেঙে যাবে you আপনি যদি এমন কোনও কীটি কল করেন যা ব্যাকিং মানচিত্রে নেই, তবে এটি ভেঙে যাবে you যদি আপনি এমন কিছু করেন যা যদি কোনও চাবিতে অনুসন্ধানের কারণ হয়ে না থাকে তবে মানচিত্র - একটি মানচিত্র.এককল কল, এতে কী, যে কোনও কিছু রয়েছে - এটি সত্যই অদ্ভুত স্ট্যাকের চিহ্ন দিয়ে ভেঙে যাবে। plus.google.com/102216152814616302326/posts/bEQLDK712MJ
haylem

339

জাভা 8 একটি নতুন উত্তর সরবরাহ করে: এন্ট্রিগুলিকে একটি স্ট্রিমে রূপান্তর করুন এবং মানচিত্রের তুলক সংযোগকারীগুলি ব্যবহার করুন ntএন্ট্রি:

Stream<Map.Entry<K,V>> sorted =
    map.entrySet().stream()
       .sorted(Map.Entry.comparingByValue());

এটি আপনাকে মান বাড়ার ক্রম অনুসারে বাছাই করা এন্ট্রিগুলি গ্রাস করতে দেবে। আপনি যদি অবতরণ মান চান, কেবল তুলনামূলক বিপরীত:

Stream<Map.Entry<K,V>> sorted =
    map.entrySet().stream()
       .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()));

মানগুলি তুলনাযোগ্য না হলে আপনি একটি সুস্পষ্ট তুলনামূলক পাস করতে পারেন:

Stream<Map.Entry<K,V>> sorted =
    map.entrySet().stream()
       .sorted(Map.Entry.comparingByValue(comparator));

এরপরে আপনি ডেটা গ্রাস করতে অন্যান্য স্ট্রিম অপারেশনগুলি ব্যবহার করতে এগিয়ে যেতে পারেন। উদাহরণস্বরূপ, আপনি যদি নতুন মানচিত্রে শীর্ষ 10 চান:

Map<K,V> topTen =
    map.entrySet().stream()
       .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
       .limit(10)
       .collect(Collectors.toMap(
          Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));

বা এতে মুদ্রণ করুন System.out:

map.entrySet().stream()
   .sorted(Map.Entry.comparingByValue())
   .forEach(System.out::println);

ভাল, তবে parallelStream()এই ক্ষেত্রে ব্যবহার সম্পর্কে কী ?
বেনজ

11
এটি সমান্তরালে কাজ করবে, তবে, আপনি দেখতে পাচ্ছেন যে আংশিক ফলাফলগুলিকে একত্রিত করতে মানচিত্রগুলিকে মার্জ করার ব্যয়টি খুব ব্যয়বহুল এবং সমান্তরাল সংস্করণটি আপনি যেমন আশা করেছিলেন তেমন সম্পাদন করতে পারে না। তবে এটি কাজ করে এবং সঠিক উত্তর উত্পাদন করে।
ব্রায়ান গোয়েজ

আপনার দরকারী পরামর্শের জন্য ধন্যবাদ। এটি ঠিক কী ছিল তা আমি ভাবছিলাম, যদিও এটি নির্ভর করে আপনি কী কী কী কী ব্যবহার করেন এবং এতগুলি পরামিতি ... গুরুত্বপূর্ণ জিনিসটি "এটি কাজ করে এবং সঠিক উত্তর উত্পাদন করে"।
বেনজ

2
শীর্ষ 10 উদাহরণে আপনাকে তুলনা বাইওয়ালু ব্যবহার করতে হবে না?
লিও

1
@ বেঞ্জ এটি শীর্ষ -10 নিষ্কাশন করার ক্ষেত্রে কাজ করবে, তবে ফলস্বরূপ মানচিত্রটির আর আদেশ করা হবে না।
অরেঞ্জডগ

211

তিনটি 1-লাইনের উত্তর ...

আমি এটি করতে গুগল কালেকশন পেয়ারা ব্যবহার করব - যদি আপনার মান হয় Comparableতবে আপনি এটি ব্যবহার করতে পারেন

valueComparator = Ordering.natural().onResultOf(Functions.forMap(map))

যা মানচিত্রের জন্য একটি ফাংশন (অবজেক্ট) তৈরি করবে [যা কোনও কীটি ইনপুট হিসাবে গ্রহণ করে, সংশ্লিষ্ট মানটি ফিরিয়ে দেবে] এবং তারপরে তাদেরকে [মানগুলি] অর্ডার করে প্রাকৃতিক (তুলনীয়) প্রয়োগ করবে।

যদি সেগুলি তুলনামূলক না হয়, তবে আপনার লাইনের সাথে কিছু করা দরকার

valueComparator = Ordering.from(comparator).onResultOf(Functions.forMap(map)) 

এগুলি একটি ট্রি ম্যাপ ( Orderingপ্রসারিত হিসাবে Comparator) বা কিছু বাছাইয়ের পরে লিংকডহ্যাশম্যাপে প্রয়োগ করা যেতে পারে

বিশেষ দ্রষ্টব্য : যদি আপনি TreeMap ব্যবহার করতে যাচ্ছি, তাহলে মনে রাখবেন যে যদি একটি তুলনা == 0, তারপর আইটেমটি ইতিমধ্যে তালিকা (যা আপনি যে একই তুলনা একাধিক মান আছে ঘটবে) রয়েছে। এটিকে হ্রাস করতে, আপনি আপনার কীটি তুলকের তুলনায় এমনভাবে যুক্ত করতে পারেন (ধরে নেওয়া যে আপনার কী এবং মানগুলি Comparable):

valueComparator = Ordering.natural().onResultOf(Functions.forMap(map)).compound(Ordering.natural())

= কী দ্বারা মানচিত মানটিতে প্রাকৃতিক ক্রম প্রয়োগ করুন এবং কীটির প্রাকৃতিক অর্ডিংয়ের সাথে মিশ্রণ করুন

লক্ষ্য করুন এই এখনও যদি আপনার কী-0 তুলনা, কিন্তু এই সবচেয়ে জন্য যথেষ্ট হওয়া উচিত কাজ করবে না comparableআইটেম (যেমন hashCode, equalsএবং compareToসুসংগত প্রায়ই ...)

দেখুন Ordering.onResultOf () এবং Functions.forMap ()

বাস্তবায়ন

সুতরাং এখন আমরা একটি তুলনাকারী পেয়েছি যা আমরা যা করতে চাই তা করে, আমাদের এটি থেকে ফলাফল নেওয়া দরকার।

map = ImmutableSortedMap.copyOf(myOriginalMap, valueComparator);

এখন এটি সম্ভবত কাজ করবে তবে:

  1. একটি সম্পূর্ণ সমাপ্ত মানচিত্র দেওয়া প্রয়োজন
  2. উপরের তুলনামূলকগুলিকে একটিতে চেষ্টা করবেন না TreeMap; কোনও keyোকানো কীটির সাথে তুলনা করার চেষ্টা করার কোনও মানে নেই যখন পুটের পরে এটির কোনও মূল্য নেই, অর্থাত্ এটি সত্যই দ্রুত ভেঙে যাবে

পয়েন্ট 1 আমার জন্য কিছুটা চুক্তি-বিভক্তকারী; গুগল সংগ্রহগুলি অবিশ্বাস্যরূপে অলস (যা ভাল: আপনি তাত্ক্ষণিকভাবে প্রতিটি অপারেশন করতে পারেন; ফলাফলটি ব্যবহার শুরু করার সাথে আসল কাজটি সম্পন্ন করা হয়) এবং এর জন্য পুরো মানচিত্রটি অনুলিপি করা দরকার !

"পূর্ণ" উত্তর / মান অনুসারে লাইভ বাছাই করা মানচিত্র

যদিও চিন্তা করবেন না; যদি আপনি "লাইভ" মানচিত্রটি এইভাবে সাজানো নিয়ে যথেষ্ট ক্ষুধার্ত হয়ে থাকেন তবে নীচের মতো উন্মাদ কিছু দিয়ে আপনি উপরের বিষয়গুলির একটি ছাড়া উভয় (!) সমাধান করতে পারেন:

দ্রষ্টব্য: এটি ২০১২ সালের জুনে উল্লেখযোগ্যভাবে পরিবর্তিত হয়েছে - আগের কোডটি কখনই কাজ করতে পারে না: TreeMap.get()-> compare()এবং compare()-> এর মধ্যে অসীম লুপ তৈরি না করে মানগুলি অনুসন্ধান করার জন্য একটি অভ্যন্তরীণ হ্যাশম্যাপ প্রয়োজন isget()

import static org.junit.Assert.assertEquals;

import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

import com.google.common.base.Functions;
import com.google.common.collect.Ordering;

class ValueComparableMap<K extends Comparable<K>,V> extends TreeMap<K,V> {
    //A map for doing lookups on the keys for comparison so we don't get infinite loops
    private final Map<K, V> valueMap;

    ValueComparableMap(final Ordering<? super V> partialValueOrdering) {
        this(partialValueOrdering, new HashMap<K,V>());
    }

    private ValueComparableMap(Ordering<? super V> partialValueOrdering,
            HashMap<K, V> valueMap) {
        super(partialValueOrdering //Apply the value ordering
                .onResultOf(Functions.forMap(valueMap)) //On the result of getting the value for the key from the map
                .compound(Ordering.natural())); //as well as ensuring that the keys don't get clobbered
        this.valueMap = valueMap;
    }

    public V put(K k, V v) {
        if (valueMap.containsKey(k)){
            //remove the key in the sorted set before adding the key again
            remove(k);
        }
        valueMap.put(k,v); //To get "real" unsorted values for the comparator
        return super.put(k, v); //Put it in value order
    }

    public static void main(String[] args){
        TreeMap<String, Integer> map = new ValueComparableMap<String, Integer>(Ordering.natural());
        map.put("a", 5);
        map.put("b", 1);
        map.put("c", 3);
        assertEquals("b",map.firstKey());
        assertEquals("a",map.lastKey());
        map.put("d",0);
        assertEquals("d",map.firstKey());
        //ensure it's still a map (by overwriting a key, but with a new value) 
        map.put("d", 2);
        assertEquals("b", map.firstKey());
        //Ensure multiple values do not clobber keys
        map.put("e", 2);
        assertEquals(5, map.size());
        assertEquals(2, (int) map.get("e"));
        assertEquals(2, (int) map.get("d"));
    }
 }

যখন আমরা রাখি, আমরা নিশ্চিত করি যে হ্যাশ মানচিত্রে তুলকের জন্য মান রয়েছে এবং তার পরে বাছাইয়ের জন্য ট্রিসেটে রেখেছি। তবে এর আগে আমরা হ্যাশ ম্যাপটি পরীক্ষা করে দেখি যে কীটি আসলে কোনও সদৃশ নয়। এছাড়াও, আমরা যে তুলনামূলকটি তৈরি করি তা কীটিও অন্তর্ভুক্ত করবে যাতে সদৃশ মানগুলি নন-সদৃশ কীগুলি (== তুলনার কারণে) মুছবে না। এই 2 টি আইটেম মানচিত্র চুক্তি রাখা নিশ্চিত করার জন্য অতীব গুরুত্বপূর্ণ ; যদি আপনি ভাবেন যে আপনি এটি চান না, তবে আপনি প্রায় পুরোপুরি মানচিত্রে (পরিবর্তিত Map<V,K>) ফিরতে চলেছেন )

কনস্ট্রাক্টর হিসাবে হিসাবে কল করা প্রয়োজন

 new ValueComparableMap(Ordering.natural());
 //or
 new ValueComparableMap(Ordering.from(comparator));

হাই @ স্টিফেন, আপনি কীভাবে অর্ডারিং ব্যবহার করবেন একটি উদাহরণ দিতে পারেন? আমি অর্ডারিংয়ের সোর্স কোডটি খতিয়ে দেখি এবং সম্পূর্ণরূপে বুঝতে পারি না যে .n Natural ()। OnResultOf (...) কী দেয়! উত্স কোডটি "সার্বজনীন <F> অর্ডার <F> onResultOf", আমি জানি না এটি কীভাবে সংকলিত হয়! সর্বাধিক গুরুত্বপূর্ণ, কীভাবে একটি মানচিত্র বাছাই করতে "<F> অর্ডারিং <F>" ব্যবহার করবেন? এটি কি তুলনামূলক বা কিছু? ধন্যবাদ।
smallufo

Orderingসহজভাবে একটি ধনী Comparator। আমি প্রতিটি উদাহরণ মন্তব্য করার চেষ্টা করেছি (প্রতিটি নীচে তির্যক)। "প্রাকৃতিক" নির্দেশ করে যে বস্তুগুলি Comparable; এটি অ্যাপাচি সাধারণের তুলনামূলক কমপ্লেটারের মতো। onResultOfতুলনা করা আইটেম একটি ফাংশন প্রয়োগ। সুতরাং আপনার যদি কোনও ফাংশন থাকে যা কোনও পূর্ণসংখ্যার সাথে 1 যোগ করে, তবে natural().onResultOf(add1Function).compare(1,2)শেষ হয়ে যাবে2.compareTo(3)
স্টিফেন

মূল মানচিত্রে সদৃশ মান থাকলে ইমিউটটেবলসোর্টডম্যাপকপি অফ ইলিজালআর্গগমেন্টএক্সেপশন নিক্ষেপ করে।
lbalazscs

@ ইবালাজস্কস হ্যাঁ এটি করবে - আপনার সদৃশ ভেরিয়েবলগুলির সংগ্রহ ImmutableSetMultiMapবা ব্যবহার করতে সক্ষম হওয়া উচিত ImmutableListMultiMap
স্টিফেন

1
এর জন্য ধন্যবাদ, আমি আপনার প্রকল্পটি একটি প্রকল্পে ব্যবহার করেছি। আমি মনে করি যদিও এতে সমস্যা আছে: মানচিত্রের মতো আচরণ করার জন্য আগে যদি মূলটির সাথে সম্পর্কিত মানটি উপস্থিত থাকে তবে এটি উপস্থিত থাকলেও এটি এর আগে কখনও হবে না। আমি যে সমাধানটি ব্যবহার করেছি তা হ'ল এটি যদি বিদ্যমান থাকে তবে তা মুছে ফেলা।
অলেগ

185

Http://www.programmersheaven.com/download/49349/download.aspx থেকে

private static <K, V> Map<K, V> sortByValue(Map<K, V> map) {
    List<Entry<K, V>> list = new LinkedList<>(map.entrySet());
    Collections.sort(list, new Comparator<Object>() {
        @SuppressWarnings("unchecked")
        public int compare(Object o1, Object o2) {
            return ((Comparable<V>) ((Map.Entry<K, V>) (o1)).getValue()).compareTo(((Map.Entry<K, V>) (o2)).getValue());
        }
    });

    Map<K, V> result = new LinkedHashMap<>();
    for (Iterator<Entry<K, V>> it = list.iterator(); it.hasNext();) {
        Map.Entry<K, V> entry = (Map.Entry<K, V>) it.next();
        result.put(entry.getKey(), entry.getValue());
    }

    return result;
}

16
যে তালিকাটি বাছাই করা হবে তা হ'ল "নতুন লিংকডলিস্ট" ?? ঘি। কৃতজ্ঞতার সাথে সংগ্রহগুলি.সোর্ট () প্রথমে এই ধরণের ত্রুটি এড়াতে প্রথমে একটি অ্যারেতে তালিকাটি ফেলে দিন (তবে তবুও, একটি অ্যারেতে অ্যারেলিস্ট ডাম্পিং লিঙ্কডলিস্টের জন্য একই কাজ করার চেয়ে দ্রুত হওয়া উচিত)।
দিমিত্রিস আন্দ্রেউ

Iterator থেকে TernaryTree- এ রূপান্তর করতে পারবেন না teআলক্ষক
লিসাক

4
@ gg.kaspersky আমি বলছি না "লিংকডলিস্ট বাছাই করা খারাপ", তবে লিংকডলিস্ট এখানে বাছাই না করেই এখানে খারাপ পছন্দ choice অনেক ভাল একটি ArrayList ব্যবহার করতে, এবং অতিরিক্ত পয়েন্ট, আকার এ ঠিক map.size ()। এছাড়াও অ্যারেলিস্টে উপাদান অনুসারে কোড. google.com/p/memory-measurer/wiki/… গড় মূল্য: লিঙ্কডলিস্ট: 24 বাইটে উপাদান হিসাবে প্রতি বাইট গড় ব্যয়। সঠিক আকারের অ্যারেলিস্টের জন্য, গড় ব্যয় হবে 4 বাইট। অর্থাৎ লিঙ্কলিস্ট অ্যারেলিস্টের যে পরিমাণ মেমরির প্রয়োজন তা ছয় গুণ নেয় takes এটি সবেমাত্র
ফুলে উঠেছে

2
উপরের মানগুলি ব্যবহার করে আরোহী ক্রম অনুসারে বাছাই করা হয়েছে। সাজানো কিভাবে সাজানো?
রাম 13

1
অবতরণকে সাজানোর জন্য o1 এবং o2 প্রতিস্থাপন করুন।
সোহেল

68

জাভা 8 এর সাহায্যে আপনি এপিআই স্টিমগুলি উল্লেখযোগ্যভাবে কম ভার্বোজ উপায়ে এটি ব্যবহার করতে পারেন :

Map<K, V> sortedMap = map.entrySet().stream()
                         .sorted(Entry.comparingByValue())
                         .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));

বিপরীত ক্রমে এটি কীভাবে বাছাই করবেন?
ভ্লাদ হলুবিভ

6
একটি সমাধান খুঁজে পেয়েছি -Collections.reverseOrder(comparing(Entry::getValue))
ভ্লাদ হলুবিভ

1
আমার মনে হয় আমি সেখানে একটি টাইপো দেখছি - "টু ম্যাপ" কে "সংগ্রাহক। টোম্যাপ ()" বলা উচিত নয়?
জেক স্টোকস

1
@ জ্যাকস্টোকস বা একটি স্ট্যাটিক আমদানি ব্যবহার করুন :-)
অ্যাসিলিয়াস

6
বিপরীত ক্রমে প্রবেশের মান অনুসারে বাছাই করার একটি আরও ভাল উপায়:Entry.comparingByValue(Comparator.reverseOrder())
গেডিমিনাস রিমসা

31

কীগুলি বাছাই করার জন্য প্রতিটি তুলনার জন্য প্রতিটি মান সন্ধানকারীকে তুলনামূলক প্রয়োজন। আরও একটি পরিমাপযোগ্য সমাধান সরাসরি এন্ট্রিসেটটি সরাসরি ব্যবহার করবে, তার পর থেকে প্রতিটি তুলনা করার জন্য মানটি সাথে সাথে উপলব্ধ হবে (যদিও আমি এটি সংখ্যা দ্বারা ব্যাক আপ করি নি)।

এই জাতীয় জিনিসের একটি জেনেরিক সংস্করণ এখানে:

public static <K, V extends Comparable<? super V>> List<K> getKeysSortedByValue(Map<K, V> map) {
    final int size = map.size();
    final List<Map.Entry<K, V>> list = new ArrayList<Map.Entry<K, V>>(size);
    list.addAll(map.entrySet());
    final ValueComparator<V> cmp = new ValueComparator<V>();
    Collections.sort(list, cmp);
    final List<K> keys = new ArrayList<K>(size);
    for (int i = 0; i < size; i++) {
        keys.set(i, list.get(i).getKey());
    }
    return keys;
}

private static final class ValueComparator<V extends Comparable<? super V>>
                                     implements Comparator<Map.Entry<?, V>> {
    public int compare(Map.Entry<?, V> o1, Map.Entry<?, V> o2) {
        return o1.getValue().compareTo(o2.getValue());
    }
}

উপরের সমাধানের জন্য মেমরি ঘূর্ণন হ্রাস করার উপায় রয়েছে। তৈরি করা প্রথম অ্যারেলিস্ট উদাহরণস্বরূপ রিটার্ন মান হিসাবে পুনরায় ব্যবহার করা যেতে পারে; এর জন্য কিছু জেনেরিক সতর্কতা দমন করতে হবে তবে এটি পুনরায় ব্যবহারযোগ্য লাইব্রেরি কোডের জন্য উপযুক্ত। এছাড়াও, প্রতিটি অনুরোধে তুলনাকারীকে পুনরায় বরাদ্দ করতে হবে না।

এখানে কম আবেদনকারী সংস্করণ হলেও আরও দক্ষ:

public static <K, V extends Comparable<? super V>> List<K> getKeysSortedByValue2(Map<K, V> map) {
    final int size = map.size();
    final List reusedList = new ArrayList(size);
    final List<Map.Entry<K, V>> meView = reusedList;
    meView.addAll(map.entrySet());
    Collections.sort(meView, SINGLE);
    final List<K> keyView = reusedList;
    for (int i = 0; i < size; i++) {
        keyView.set(i, meView.get(i).getKey());
    }
    return keyView;
}

private static final Comparator SINGLE = new ValueComparator();

শেষ অবধি, যদি আপনি ক্রমাগত বাছাই করা তথ্য অ্যাক্সেস করতে চান (কেবল একবারে এটি সাজানোর পরিবর্তে), আপনি অতিরিক্ত মাল্টি ম্যাপ ব্যবহার করতে পারেন। আপনার আরও বিশদ প্রয়োজন হলে আমাকে জানাবেন ...


আপনি যদি তালিকা <মানচিত্র.এন্ট্রি <কে, ভি >> ফিরিয়ে দেন তবে দ্বিতীয় সংস্করণটি আরও সংক্ষিপ্ত হতে পারে This এটিকে পুনরাবৃত্তি করা এবং কীগুলি এবং মানগুলি উভয়ই মানচিত্রে না পেয়েও সহজ হয়ে যায় easier এই কোডটি থ্রেড-অনিরাপদ হওয়ার কারণে আপনি ঠিকঠাক অনুমান করছেন। যদি ব্যাকিং মানচিত্র বা বাছাই করা তালিকাটি একটি বহুবিবাহিত পরিবেশে ভাগ করা হয় তবে সমস্ত বেট বন্ধ রয়েছে।
মাইক মিলার

26

কমন্স-কালেকশন লাইব্রেরিতে ট্রিবিডিম্যাপ নামে একটি সমাধান রয়েছে । অথবা, আপনি গুগল সংগ্রহগুলি এপিআই এ দেখতে পারেন। এটা আছে TreeMultimap যা আপনি ব্যবহার করতে পারেন।

এবং যদি আপনি এই কাঠামোটি ব্যবহার করতে না চান ... তারা উত্স কোড সহ আসে।


আপনাকে কমন্স-সংগ্রহ ব্যবহার করতে হবে না। জাভা তার নিজস্ব java.util.TreeMap নিয়ে আসে।
yoliho

2
হ্যাঁ, কিন্তু TreeMap গেলে কখন অন বাছাই অনেক কম নমনীয় মান mapentries অংশ।
p3t0r

9
বিডিম্যাপের সমস্যাটি হ'ল এটি সম্পর্কটিকে অবিচ্ছিন্ন করার জন্য কী এবং মানগুলির মধ্যে 1: 1 সম্পর্কের অন্তরায় যুক্ত করে (অর্থাত্ কী এবং মান উভয়ই অনন্য হওয়া দরকার)। এর অর্থ আপনি শব্দের গণনা অবজেক্টের মতো কিছু সঞ্চয় করতে এটি ব্যবহার করতে পারবেন না কারণ অনেক শব্দের একই গণনা থাকবে।
ডগ

26

আমি প্রদত্ত উত্তরগুলিতে নজর রেখেছি, তবে বেশিরভাগ কীগুলির একই মান থাকলে মানচিত্রের অনেকগুলি প্রয়োজনের চেয়ে জটিল বা মানচিত্রের উপাদানগুলি সরিয়ে দেয়।

এখানে একটি সমাধান যা আমি মনে করি এটি আরও ভাল ফিট করে:

public static <K, V extends Comparable<V>> Map<K, V> sortByValues(final Map<K, V> map) {
    Comparator<K> valueComparator =  new Comparator<K>() {
        public int compare(K k1, K k2) {
            int compare = map.get(k2).compareTo(map.get(k1));
            if (compare == 0) return 1;
            else return compare;
        }
    };
    Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
    sortedByValues.putAll(map);
    return sortedByValues;
}

নোট করুন মানচিত্রটি সর্বোচ্চ মান থেকে সর্বনিম্নে সাজানো হয়েছে।


6
সমস্যা: আপনি যদি ফেরত মানচিত্রটি পরে ব্যবহার করতে চান, উদাহরণস্বরূপ এটিতে কোনও নির্দিষ্ট উপাদান রয়েছে কিনা তা পরীক্ষা করার জন্য, আপনি আপনার কাস্টম তুলনাকারীর কারণে সর্বদা মিথ্যা হয়ে যাবেন! একটি সম্ভাব্য সমাধান: এর সাথে শেষ লাইনটি প্রতিস্থাপন করুন: নতুন লিংকডহ্যাশম্যাপ <কে, ভি> (সোর্টডবাইভ্যালুগুলি) ফিরিয়ে দিন;
এরেল সেগাল-হালেভি

এটি আমার কাছে একটি পরিষ্কার সমাধান দেখায়, কেবলমাত্র @ এরেলসেগাল হালেভি উল্লেখ করেছিলেন, মানচিত্রের মধ্যে যে মানগুলি রয়েছে তার তুলনা করে আপনি যে তুলনাটি নির্দিষ্ট করেছেন তা সম্ভব হবে না কিনা তা যাচাই করে। মানচিত্র.পুট ("1", "এক"); মানচিত্র.পুট ("2", "দুই"); মানচিত্র.পুট ("3", "তিন"); মানচিত্র.পুট ("4", "চার"); মানচিত্র.পুট ("5", "পাঁচ"); map.containsKey ("1") সর্বদা মিথ্যা প্রত্যাবর্তন করবে, আপনি যদি নতুন নতুন ট্রিম্যাপ <কে, ভি> (সোর্টডবাইভ্যালু) এর মতো সারণিওয়াইভ্যালু () ফাংশনে নতুন অবজেক্টটি ফিরিয়ে দেন; সমস্যা সমাধান করে ধন্যবাদ Abhi
Abhi

ব্যবহারকারীর 157196 এর এবং কার্টার পৃষ্ঠার উত্তরের মতোই। কার্টার পৃষ্ঠার LinkedHashMap ফিক্স রয়েছে
কারবি

সমাধানের চতুর্থ লাইনটি int comp = map.get (k1) .compareTo (map.get (k2)) হওয়া উচিত; আপনার যদি আরোহণের আদেশের প্রয়োজন হয়
www.Decompiler.com

19

জাভা 8-এ নতুন বৈশিষ্ট্যগুলি সহ এটি সম্পাদন করতে:

import static java.util.Map.Entry.comparingByValue;
import static java.util.stream.Collectors.toList;

<K, V> List<Entry<K, V>> sort(Map<K, V> map, Comparator<? super V> comparator) {
    return map.entrySet().stream().sorted(comparingByValue(comparator)).collect(toList());
}

প্রদত্ত তুলনামূলক ব্যবহার করে এন্ট্রিগুলি তাদের মান অনুসারে অর্ডার করা হয়। বিকল্পভাবে, যদি আপনার মানগুলি পারস্পরিক তুলনামূলক হয় তবে কোনও সুস্পষ্ট তুলনাকারীর প্রয়োজন নেই:

<K, V extends Comparable<? super V>> List<Entry<K, V>> sort(Map<K, V> map) {
    return map.entrySet().stream().sorted(comparingByValue()).collect(toList());
}

প্রত্যাশিত তালিকাটি এই পদ্ধতিটি বলা হওয়ার সময় প্রদত্ত মানচিত্রের একটি স্ন্যাপশট, সুতরাং অন্যটিতে পরবর্তী পরিবর্তনগুলিও প্রতিফলিত হবে না। মানচিত্রের লাইভ পুনরাবৃত্তিযোগ্য দর্শনের জন্য:

<K, V extends Comparable<? super V>> Iterable<Entry<K, V>> sort(Map<K, V> map) {
    return () -> map.entrySet().stream().sorted(comparingByValue()).iterator();
}

প্রত্যাবর্তিত পুনরাবৃত্তযোগ্য প্রদত্ত মানচিত্রের প্রতিটিবার পুনরাবৃত্তি হওয়ার পরে একটি নতুন স্ন্যাপশট তৈরি করে, সুতরাং সমবর্তী পরিবর্তনগুলি বাদ দিয়ে, এটি সর্বদা মানচিত্রের বর্তমান অবস্থাকে প্রতিফলিত করবে।


এটি মান অনুসারে বাছাই করা মানচিত্রের পরিবর্তে এন্ট্রিগুলির একটি তালিকা ফেরত দেয়। অন্যান্য সংস্করণ যা একটি মানচিত্র ফেরৎ: stackoverflow.com/a/22132422/829571
assylias

17

কাস্টমাইজড তুলনা তৈরি করুন এবং নতুন ট্রিম্যাপ অবজেক্ট তৈরি করার সময় এটি ব্যবহার করুন।

class MyComparator implements Comparator<Object> {

    Map<String, Integer> map;

    public MyComparator(Map<String, Integer> map) {
        this.map = map;
    }

    public int compare(Object o1, Object o2) {

        if (map.get(o2) == map.get(o1))
            return 1;
        else
            return ((Integer) map.get(o2)).compareTo((Integer)     
                                                            map.get(o1));

    }
}

আপনার মূল ফানকে নীচের কোডটি ব্যবহার করুন

    Map<String, Integer> lMap = new HashMap<String, Integer>();
    lMap.put("A", 35);
    lMap.put("B", 75);
    lMap.put("C", 50);
    lMap.put("D", 50);

    MyComparator comparator = new MyComparator(lMap);

    Map<String, Integer> newMap = new TreeMap<String, Integer>(comparator);
    newMap.putAll(lMap);
    System.out.println(newMap);

আউটপুট:

{B=75, D=50, C=50, A=35}

ক্ষেত্রে মানগুলি সমান হলে, কীগুলি তুলনা করতে আমি "রিটার্ন 1" লাইনটি পরিবর্তন করেছি: "রিটার্ন ((স্ট্রিং) o1) .compareTo ((স্ট্রিং) o2);"
gjgjgj

14

যদিও আমি একমত যে মানচিত্রের ধরণের ধ্রুবক প্রয়োজন সম্ভবত একটি গন্ধ, তবে আমি মনে করি যে অন্য কোনও ডেটা কাঠামো ব্যবহার না করে নিম্নলিখিত কোডটি এটি করার সবচেয়ে সহজ উপায়।

public class MapUtilities {

public static <K, V extends Comparable<V>> List<Entry<K, V>> sortByValue(Map<K, V> map) {
    List<Entry<K, V>> entries = new ArrayList<Entry<K, V>>(map.entrySet());
    Collections.sort(entries, new ByValue<K, V>());
    return entries;
}

private static class ByValue<K, V extends Comparable<V>> implements Comparator<Entry<K, V>> {
    public int compare(Entry<K, V> o1, Entry<K, V> o2) {
        return o1.getValue().compareTo(o2.getValue());
    }
}

}

এবং এখানে একটি বিব্রতকরভাবে অসম্পূর্ণ ইউনিট পরীক্ষা:

public class MapUtilitiesTest extends TestCase {
public void testSorting() {
    HashMap<String, Integer> map = new HashMap<String, Integer>();
    map.put("One", 1);
    map.put("Two", 2);
    map.put("Three", 3);

    List<Map.Entry<String, Integer>> sorted = MapUtilities.sortByValue(map);
    assertEquals("First", "One", sorted.get(0).getKey());
    assertEquals("Second", "Two", sorted.get(1).getKey());
    assertEquals("Third", "Three", sorted.get(2).getKey());
}

}

ফলাফলটি মানচিত্রের একটি সাজানো তালিকা nt


এই পদ্ধতিটি প্রায় একই প্রভাব সহ একটি মানচিত্র <ভি, তালিকা <কে>> অবজেক্ট তৈরির চেয়ে অনেক সহজ এবং স্বজ্ঞাত। মানচিত্রের মানচিত্রের কীগুলি হওয়া উচিত নয়, আপনি যা খুঁজছেন তা এই পরিস্থিতিতে একটি তালিকা, আইএমএইচও।
জেফ উ

এই সমাধানটি প্রচুর মানগুলির সাথে কাজ করে না, এটি আমার গণনাগুলির সাথে স্ক্রুযুক্ত (প্রতিটি কীগুলির সাথে সম্পর্কিত মান)
স্যাম লেভিন

1
এটা অদ্ভুত. আপনি বিস্তারিত বলতে পারেন? আপনার আউটপুটটি কী ছিল এবং আপনি কী আউটপুট আশা করেছিলেন?
লিউডমিল

12

জেনেরিক তুলনামূলক ব্যবহার করুন যেমন:

final class MapValueComparator<K,V extends Comparable<V>> implements Comparator<K> {

    private Map<K,V> map;

    private MapValueComparator() {
        super();
    }

    public MapValueComparator(Map<K,V> map) {
        this();
        this.map = map;
    }

    public int compare(K o1, K o2) {
        return map.get(o1).compareTo(map.get(o2));
    }
}

11

যখন আপনার কাছে সমান 2 আইটেম থাকে তখন উত্তরটি সবচেয়ে বেশি ভোট দেয় for ট্রিম্যাপ সমান মান ছেড়ে যায়।

দ্য এক্সমেল: অরসেটেড ম্যাপ

কী / মান: ডি / 67.3
কী / মান: এ / 99.5
কী / মান: বি / 67.4
কী / মান: সি / 67.5
কী / মান: ই / 99.5

ফলাফল

কী / মান: এ / 99.5
কী / মান: সি / 67.5
কী / মান: বি / 67.4
কী / মান: ডি / 67.3

তাই E ছাড়িয়ে যায় !!

আমার জন্য এটি তুলনাকারী সামঞ্জস্য করার জন্য দুর্দান্ত কাজ করেছে, যদি এটি 0 তবে -1 ফেরত না।

উদাহরণে:

শ্রেণি মান মূল্য সংযোগকারী তুলনামূলক প্রয়োগ করে {

মানচিত্র বেস; পাবলিক ভ্যালুকমারেটর (মানচিত্র বেস) {this.base = বেস; }

সর্বজনীন int তুলনা (অবজেক্ট এ, অবজেক্ট বি) {

if((Double)base.get(a) < (Double)base.get(b)) {
  return 1;
} else if((Double)base.get(a) == (Double)base.get(b)) {
  return -1;
} else {
  return -1;
}

}}

এখন এটি ফিরে আসে:

অরক্ষিত মানচিত্র:

কী / মান: ডি / 67.3
কী / মান: এ / 99.5
কী / মান: বি / 67.4
কী / মান: সি / 67.5
কী / মান: ই / 99.5

ফলাফল:

কী / মান: এ / 99.5
কী / মান: ই / 99.5
কী / মান: সি / 67.5
কী / মান: বি / 67.4
কী / মান: ডি / 67.3

এলিয়েনের প্রতিক্রিয়া হিসাবে (২০১১ নভেম্বর 22): আমি এই সমাধানটি ইন্টিজার আইডি এবং নামগুলির মানচিত্রের জন্য ব্যবহার করছি, তবে ধারণাটি একই, সুতরাং উপরের কোডটি সঠিক নাও হতে পারে (আমি এটি একটি পরীক্ষায় লিখব) এবং আপনাকে সঠিক কোডটি দেবেন), এটি উপরের সমাধানের ভিত্তিতে মানচিত্রের বাছাইয়ের কোড:

package nl.iamit.util;

import java.util.Comparator;
import java.util.Map;

public class Comparators {


    public static class MapIntegerStringComparator implements Comparator {

        Map<Integer, String> base;

        public MapIntegerStringComparator(Map<Integer, String> base) {
            this.base = base;
        }

        public int compare(Object a, Object b) {

            int compare = ((String) base.get(a))
                    .compareTo((String) base.get(b));
            if (compare == 0) {
                return -1;
            }
            return compare;
        }
    }


}

এবং এটি পরীক্ষা শ্রেণি (আমি কেবল এটি পরীক্ষা করেছি এবং এটি পূর্ণসংখ্যার জন্য কাজ করে, স্ট্রিং ম্যাপ:

package test.nl.iamit.util;

import java.util.HashMap;
import java.util.TreeMap;
import nl.iamit.util.Comparators;
import org.junit.Test;
import static org.junit.Assert.assertArrayEquals;

public class TestComparators {


    @Test
    public void testMapIntegerStringComparator(){
        HashMap<Integer, String> unSoretedMap = new HashMap<Integer, String>();
        Comparators.MapIntegerStringComparator bvc = new Comparators.MapIntegerStringComparator(
                unSoretedMap);
        TreeMap<Integer, String> sorted_map = new TreeMap<Integer, String>(bvc);
        //the testdata:
        unSoretedMap.put(new Integer(1), "E");
        unSoretedMap.put(new Integer(2), "A");
        unSoretedMap.put(new Integer(3), "E");
        unSoretedMap.put(new Integer(4), "B");
        unSoretedMap.put(new Integer(5), "F");

        sorted_map.putAll(unSoretedMap);

        Object[] targetKeys={new Integer(2),new Integer(4),new Integer(3),new Integer(1),new Integer(5) };
        Object[] currecntKeys=sorted_map.keySet().toArray();

        assertArrayEquals(targetKeys,currecntKeys);
    }
}

এখানে একটি মানচিত্রের তুলনাকারীর কোড রয়েছে:

public static class MapStringDoubleComparator implements Comparator {

    Map<String, Double> base;

    public MapStringDoubleComparator(Map<String, Double> base) {
        this.base = base;
    }

    //note if you want decending in stead of ascending, turn around 1 and -1
    public int compare(Object a, Object b) {
        if ((Double) base.get(a) == (Double) base.get(b)) {
            return 0;
        } else if((Double) base.get(a) < (Double) base.get(b)) {
            return -1;
        }else{
            return 1;
        }
    }
}

এবং এটি এটির জন্য টেস্টকেস:

@Test
public void testMapStringDoubleComparator(){
    HashMap<String, Double> unSoretedMap = new HashMap<String, Double>();
    Comparators.MapStringDoubleComparator bvc = new Comparators.MapStringDoubleComparator(
            unSoretedMap);
    TreeMap<String, Double> sorted_map = new TreeMap<String, Double>(bvc);
    //the testdata:
    unSoretedMap.put("D",new Double(67.3));
    unSoretedMap.put("A",new Double(99.5));
    unSoretedMap.put("B",new Double(67.4));
    unSoretedMap.put("C",new Double(67.5));
    unSoretedMap.put("E",new Double(99.5));

    sorted_map.putAll(unSoretedMap);

    Object[] targetKeys={"D","B","C","E","A"};
    Object[] currecntKeys=sorted_map.keySet().toArray();

    assertArrayEquals(targetKeys,currecntKeys);
}

উত্স সম্পর্কে আপনি এটিকে অনেক বেশি জেনেরিক তৈরি করতে পারেন তবে 1 টি ক্ষেত্রে এটির দরকার ছিল (মানচিত্র)


আপনি ঠিক বলেছেন, কোডটি আমি প্রথমে দিয়েছিলাম তাতে কিছু ত্রুটি ছিল! আমি আশা করি আমার সাম্প্রতিক সম্পাদনাটি আপনাকে সহায়তা করবে।
michel.iamit

9

Collections.sortকিছু হিসাবে ব্যবহার না করে আমি ব্যবহার করার পরামর্শ দিই Arrays.sort। আসলে কি Collections.sortকরে এরকম কিছু:

public static <T extends Comparable<? super T>> void sort(List<T> list) {
    Object[] a = list.toArray();
    Arrays.sort(a);
    ListIterator<T> i = list.listIterator();
    for (int j=0; j<a.length; j++) {
        i.next();
        i.set((T)a[j]);
    }
}

এটি কেবল toArrayতালিকায় কল করে এবং তারপরে ব্যবহার করে Arrays.sort। এইভাবে সমস্ত মানচিত্রের এন্ট্রিগুলি তিনবার অনুলিপি করা হবে: একবার মানচিত্র থেকে অস্থায়ী তালিকায় (এটি লিংকডলিস্ট বা অ্যারেলিস্ট হতে পারে), তারপরে অস্থায়ী অ্যারে এবং শেষ পর্যন্ত নতুন মানচিত্রে।

আমার সমাধানটি এই এক ধাপ বাদ দেয় কারণ এটি অপ্রয়োজনীয় লিঙ্কলিস্ট তৈরি করে না। এখানে কোডটি, জেনেরিক-বান্ধব এবং কার্য সম্পাদন-অনুকূল:

public static <K, V extends Comparable<? super V>> Map<K, V> sortByValue(Map<K, V> map) 
{
    @SuppressWarnings("unchecked")
    Map.Entry<K,V>[] array = map.entrySet().toArray(new Map.Entry[map.size()]);

    Arrays.sort(array, new Comparator<Map.Entry<K, V>>() 
    {
        public int compare(Map.Entry<K, V> e1, Map.Entry<K, V> e2) 
        {
            return e1.getValue().compareTo(e2.getValue());
        }
    });

    Map<K, V> result = new LinkedHashMap<K, V>();
    for (Map.Entry<K, V> entry : array)
        result.put(entry.getKey(), entry.getValue());

    return result;
}

8

এটি অ্যান্টনির উত্তরের একটি প্রকরণ, যেখানে সদৃশ মান থাকলে তা কার্যকর হয় না:

public static <K, V extends Comparable<V>> Map<K, V> sortMapByValues(final Map<K, V> map) {
    Comparator<K> valueComparator =  new Comparator<K>() {
        public int compare(K k1, K k2) {
            final V v1 = map.get(k1);
            final V v2 = map.get(k2);

            /* Not sure how to handle nulls ... */
            if (v1 == null) {
                return (v2 == null) ? 0 : 1;
            }

            int compare = v2.compareTo(v1);
            if (compare != 0)
            {
                return compare;
            }
            else
            {
                Integer h1 = k1.hashCode();
                Integer h2 = k2.hashCode();
                return h2.compareTo(h1);
            }
        }
    };
    Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
    sortedByValues.putAll(map);
    return sortedByValues;
}

নোটগুলি কীভাবে পরিচালনা করতে হবে তা বাতাসের মধ্যেই নোট করুন।

এই পদ্ধতির একটি গুরুত্বপূর্ণ সুবিধা হ'ল এটি এখানে দেওয়া অন্যান্য সমাধানগুলির থেকে পৃথক করে একটি মানচিত্র ফিরিয়ে দেয়।


এটি ভুল, ডুপ্লিকেট মান থাকলে আমার পদ্ধতি কাজ করে। আমি মান হিসাবে "1" সহ 100 টিরও বেশি কী থাকা মানচিত্রে এটি ব্যবহার করেছি।
অ্যান্টনি

8

সেরা পন্থা

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry; 

public class OrderByValue {

  public static void main(String a[]){
    Map<String, Integer> map = new HashMap<String, Integer>();
    map.put("java", 20);
    map.put("C++", 45);
    map.put("Unix", 67);
    map.put("MAC", 26);
    map.put("Why this kolavari", 93);
    Set<Entry<String, Integer>> set = map.entrySet();
    List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);
    Collections.sort( list, new Comparator<Map.Entry<String, Integer>>()
    {
        public int compare( Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2 )
        {
            return (o1.getValue()).compareTo( o2.getValue() );//Ascending order
            //return (o2.getValue()).compareTo( o1.getValue() );//Descending order
        }
    } );
    for(Map.Entry<String, Integer> entry:list){
        System.out.println(entry.getKey()+" ==== "+entry.getValue());
    }
  }}

আউটপুট

java ==== 20

MAC ==== 26

C++ ==== 45

Unix ==== 67

Why this kolavari ==== 93

7

প্রধান সমস্যা. আপনি যদি প্রথম উত্তরটি ব্যবহার করেন (গুগল আপনাকে এখানে নিয়ে যায়), সমান ধারাটি যুক্ত করতে তুলনামূলক পরিবর্তন করুন, অন্যথায় আপনি কী দ্বারা সাজানো_ম্যাপ থেকে মান পেতে পারবেন না:

public int compare(String a, String b) {
        if (base.get(a) > base.get(b)) {
            return 1;
        } else if (base.get(a) < base.get(b)){
            return -1;
        } 

        return 0;
        // returning 0 would merge keys
    }

এখন আপনি যখন সমান মান সহ দুটি এন্ট্রি যুক্ত করবেন সেগুলি মার্জ হবে তবে আপনি কেবল 0 টি ফিরে আসবেন যদি আপনি নিশ্চিত হন যে অবজেক্টগুলি একই (সমান)
মাসুদ_মজে

7

ইতিমধ্যে এই প্রশ্নের জন্য অনেক উত্তর রয়েছে, কিন্তু আমি যা চেয়েছিলাম তা কিছুই আমাকে সরবরাহ করেনি, একটি মানচিত্রের প্রয়োগ যা সম্পর্কিত মান অনুসারে বাছাই করা কীগুলি এবং এন্ট্রিগুলি প্রদান করে এবং মানচিত্রে কী এবং মানগুলি পরিবর্তিত হওয়ার কারণে এই সম্পত্তিটি বজায় রাখে। অন্য দুটি প্রশ্ন বিশেষভাবে এটির জন্য জিজ্ঞাসা করে।

আমি একটি জেনেরিক বন্ধুত্বপূর্ণ উদাহরণ রান্না করেছি যা এই ব্যবহারের ক্ষেত্রে সমাধান করে। এই প্রয়োগটি মানচিত্র ইন্টারফেসের সমস্ত চুক্তিকে সম্মান দেয় না, যেমন মূল অবজেক্টে কীসেট () এবং এন্ট্রিসেট () থেকে ফিরে আসা সেটের মান পরিবর্তন এবং অপসারণকে প্রতিফলিত করে। আমি অনুভব করেছি যে স্ট্যাক ওভারফ্লো উত্তরের অন্তর্ভুক্ত করার জন্য এই জাতীয় সমাধান খুব বড় হবে। যদি আমি আরও সম্পূর্ণ বাস্তবায়ন তৈরি করতে পরিচালিত করি তবে সম্ভবত আমি এটি গিথুব এবং তারপরে এই উত্তরের একটি আপডেট সংস্করণে লিঙ্ক করব।

import java.util.*;

/**
 * A map where {@link #keySet()} and {@link #entrySet()} return sets ordered
 * by associated values based on the the comparator provided at construction
 * time. The order of two or more keys with identical values is not defined.
 * <p>
 * Several contracts of the Map interface are not satisfied by this minimal
 * implementation.
 */
public class ValueSortedMap<K, V> extends HashMap<K, V> {
    protected Map<V, Collection<K>> valueToKeysMap;

    // uses natural order of value object, if any
    public ValueSortedMap() {
        this((Comparator<? super V>) null);
    }

    public ValueSortedMap(Comparator<? super V> valueComparator) {
        this.valueToKeysMap = new TreeMap<V, Collection<K>>(valueComparator);
    }

    public boolean containsValue(Object o) {
        return valueToKeysMap.containsKey(o);
    }

    public V put(K k, V v) {
        V oldV = null;
        if (containsKey(k)) {
            oldV = get(k);
            valueToKeysMap.get(oldV).remove(k);
        }
        super.put(k, v);
        if (!valueToKeysMap.containsKey(v)) {
            Collection<K> keys = new ArrayList<K>();
            keys.add(k);
            valueToKeysMap.put(v, keys);
        } else {
            valueToKeysMap.get(v).add(k);
        }
        return oldV;
    }

    public void putAll(Map<? extends K, ? extends V> m) {
        for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
            put(e.getKey(), e.getValue());
    }

    public V remove(Object k) {
        V oldV = null;
        if (containsKey(k)) {
            oldV = get(k);
            super.remove(k);
            valueToKeysMap.get(oldV).remove(k);
        }
        return oldV;
    }

    public void clear() {
        super.clear();
        valueToKeysMap.clear();
    }

    public Set<K> keySet() {
        LinkedHashSet<K> ret = new LinkedHashSet<K>(size());
        for (V v : valueToKeysMap.keySet()) {
            Collection<K> keys = valueToKeysMap.get(v);
            ret.addAll(keys);
        }
        return ret;
    }

    public Set<Map.Entry<K, V>> entrySet() {
        LinkedHashSet<Map.Entry<K, V>> ret = new LinkedHashSet<Map.Entry<K, V>>(size());
        for (Collection<K> keys : valueToKeysMap.values()) {
            for (final K k : keys) {
                final V v = get(k);
                ret.add(new Map.Entry<K,V>() {
                    public K getKey() {
                        return k;
                    }

                    public V getValue() {
                        return v;
                    }

                    public V setValue(V v) {
                        throw new UnsupportedOperationException();
                    }
                });
            }
        }
        return ret;
    }
}

যদি তুলনামূলক এবং তুলনাকারীর অনুমতি না থাকে তবে কীভাবে এটি করা যায়?
বেদ প্রকাশ

আপনার ব্যবহারের বিষয়টি আমি বুঝতে পেরেছি কিনা তা নিশ্চিত নয়, সম্ভবত আপনি আরও বিস্তারিত বলতে পারেন। মান হিসাবে আপনি যে বস্তুটি ব্যবহার করতে ইচ্ছুক তা যদি তুলনীয় না হয় তবে আপনাকে এটিকে কোনও অবজেক্টে রূপান্তর করতে হবে।
ডেভিড ব্লেকম্যান

6

দেরীতে প্রবেশ

জাভা -8 এর আবির্ভাবের সাথে আমরা খুব সহজেই / সাফল্যের উপায়ে ডেটা ম্যানিপুলেশনের জন্য স্ট্রিম ব্যবহার করতে পারি। মান দ্বারা প্রবেশের মানকে বাছাই করতে আপনি স্ট্রিম ব্যবহার করতে পারেন এবং একটি লিঙ্কডহ্যাশম্যাপ তৈরি করতে পারেন যা সন্নিবেশ-ক্রমের পুনরাবৃত্তি সংরক্ষণ করে ।

উদাহরণ:

LinkedHashMap sortedByValueMap = map.entrySet().stream()
                .sorted(comparing(Entry<Key,Value>::getValue).thenComparing(Entry::getKey))     //first sorting by Value, then sorting by Key(entries with same value)
                .collect(LinkedHashMap::new,(map,entry) -> map.put(entry.getKey(),entry.getValue()),LinkedHashMap::putAll);

বিপরীত অর্ডারের জন্য, প্রতিস্থাপন করুন:

comparing(Entry<Key,Value>::getValue).thenComparing(Entry::getKey)

সঙ্গে

comparing(Entry<Key,Value>::getValue).thenComparing(Entry::getKey).reversed()

এই মন্তব্য করা সংস্করণ জন্য ধন্যবাদ। একটি প্রশ্ন: ব্যবহারের পার্থক্য কি Entry.comparingByValue()(assylias উপরে উত্তর হিসাবে stackoverflow.com/a/22132422/1480587 ) অথবা comparing(Entry<Key,Value>::getValue).thenComparing(Entry::getKey)ক্ষেত্রে আপনাকে ব্যবহৃত? আমি বুঝতে পারি আপনি কীগুলিও তুলনা করুন যদি মানগুলি অভিন্ন হয়, তাই না? আমি লক্ষ্য করেছি যে বাছাই করা একই মানের সাথে উপাদানের ক্রম বজায় রাখে - তাই কীগুলি দ্বারা বাছাই করা যদি কীগুলি ইতিমধ্যে পূর্বে বাছাই করা হয়?
পিটার টি।

6

প্রদত্ত মানচিত্র

   Map<String, Integer> wordCounts = new HashMap<>();
    wordCounts.put("USA", 100);
    wordCounts.put("jobs", 200);
    wordCounts.put("software", 50);
    wordCounts.put("technology", 70);
    wordCounts.put("opportunity", 200);

আরোহী ক্রমে মানের উপর ভিত্তি করে মানচিত্রটি সাজান

Map<String,Integer>  sortedMap =  wordCounts.entrySet().
                                                stream().
                                                sorted(Map.Entry.comparingByValue()).
        collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
    System.out.println(sortedMap);

ডেসেন্ডিং ক্রমে মানের ভিত্তিতে মানচিত্রটি সাজান

Map<String,Integer>  sortedMapReverseOrder =  wordCounts.entrySet().
            stream().
            sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).
            collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
    System.out.println(sortedMapReverseOrder);

আউটপুট:

{সফটওয়্যার = 50, প্রযুক্তি = 70, ইউএসএ = 100, জব = 200, সুযোগ = 200

{কাজ = 200, সুযোগ = 200, মার্কিন যুক্তরাষ্ট্র = 100, প্রযুক্তি = 70, সফ্টওয়্যার = 50


আমার ধারণা মানচিত্র-হ্রাস সত্যিই এটি "হ্রাস" হয়েছে .... ভাল সমাধান।
ha9u63ar

ধন্যবাদ @ ha9u63ar
অর্পণ

এটি কাজ করে তবে আমি বুঝতে পারি না যে হ্যাশম্যাপে উপাদানগুলির ক্রম কীভাবে আসে?
আলী টু

5

প্রসঙ্গের উপর নির্ভর করে, java.util.LinkedHashMap<T>যা ব্যবহার করে মানচিত্রে কোন আইটেম স্থাপন করা হয়েছে সেই ক্রমের কথা মনে পড়ে। অন্যথায়, যদি তাদের প্রাকৃতিক ক্রমের উপর ভিত্তি করে মানগুলি সাজানোর দরকার হয় তবে আমি পৃথক তালিকা বজায় রাখার পরামর্শ দিচ্ছি যা এর মাধ্যমে বাছাই করা যায় Collections.sort()


আমি কেন দেখছি না এটি -1, এখন পর্যন্ত লিংকডহ্যাশম্যাপটি সম্ভবত আমার পক্ষে সেরা সমাধান, আমি কেবল এটি ফেলে দিতে এবং একটি নতুন লিঙ্কডহ্যাশম্যাপ তৈরি করা কত ব্যয়বহুল তা বোঝার চেষ্টা করছি।
NobleUplift

5

যেহেতু ট্রি ম্যাপ <> সমান হতে পারে এমন মানগুলির জন্য কাজ করে না , তাই আমি এটি ব্যবহার করেছি:

private <K, V extends Comparable<? super V>> List<Entry<K, V>> sort(Map<K, V> map)     {
    List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(map.entrySet());
    Collections.sort(list, new Comparator<Map.Entry<K, V>>() {
        public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
            return o1.getValue().compareTo(o2.getValue());
        }
    });

    return list;
}

আপনি একটি লিঙ্কডহ্যাশম্যাপে তালিকাটি রাখতে চান , তবে আপনি যদি এখনই এটির পুনরুক্তি করতে চলেছেন তবে এটি অতিমাত্রায় ...


ঠিক আছে তবে আপনার তুলনাকারী সমান মানের
কেসটি

5

এটি ঠিক খুব জটিল। মানচিত্রগুলি মান দ্বারা বাছাইয়ের মতো কাজ করার কথা ছিল না। সবচেয়ে সহজ উপায় হল নিজের ক্লাস তৈরি করা যাতে এটি আপনার প্রয়োজনের সাথে খাপ খায়।

উদাহরণস্বরূপ নীচের অংশে আপনি * টি যেখানে TreeMap কে তুলনাকারী যুক্ত করার কথা। তবে জাভা এপিআই দ্বারা এটি তুলনামূলক কেবল কীগুলি দেয়, মানগুলি দেয় না। এখানে বর্ণিত সমস্ত উদাহরণ 2 মানচিত্রের ভিত্তিতে তৈরি। একটি হ্যাশ এবং একটি নতুন গাছ। যা বিজোড়।

উদাহরণ:

Map<Driver driver, Float time> map = new TreeMap<Driver driver, Float time>(*);

সুতরাং এইভাবে মানচিত্রে একটি সেটে পরিবর্তন করুন:

ResultComparator rc = new ResultComparator();
Set<Results> set = new TreeSet<Results>(rc);

আপনি ক্লাস তৈরি করবেন Results,

public class Results {
    private Driver driver;
    private Float time;

    public Results(Driver driver, Float time) {
        this.driver = driver;
        this.time = time;
    }

    public Float getTime() {
        return time;
    }

    public void setTime(Float time) {
        this.time = time;
    }

    public Driver getDriver() {
        return driver;
    }

    public void setDriver (Driver driver) {
        this.driver = driver;
    }
}

এবং তুলনামূলক শ্রেণি:

public class ResultsComparator implements Comparator<Results> {
    public int compare(Results t, Results t1) {
        if (t.getTime() < t1.getTime()) {
            return 1;
        } else if (t.getTime() == t1.getTime()) {
            return 0;
        } else {
            return -1;
        }
    }
}

আপনি সহজেই আরও নির্ভরতা যুক্ত করতে পারেন।

এবং শেষ পয়েন্ট হিসাবে আমি সহজ পুনরাবৃত্তি যুক্ত করব:

Iterator it = set.iterator();
while (it.hasNext()) {
    Results r = (Results)it.next();
    System.out.println( r.getDriver().toString
        //or whatever that is related to Driver class -getName() getSurname()
        + " "
        + r.getTime()
        );
}

4

@ দেবমিন কোডের উপর ভিত্তি করে, একটি মানচিত্র জেনেরিকগুলি ব্যবহার করে এবং আরোহণ এবং উতরাই উভয় ক্রম সমর্থন করে methods

/**
 * Sort a map by it's keys in ascending order. 
 *  
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMapByKey(final Map<K, V> map) {
    return sortMapByKey(map, SortingOrder.ASCENDING);
}

/**
 * Sort a map by it's values in ascending order.
 *  
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMapByValue(final Map<K, V> map) {
    return sortMapByValue(map, SortingOrder.ASCENDING);
}

/**
 * Sort a map by it's keys.
 *  
 * @param sortingOrder {@link SortingOrder} enum specifying requested sorting order. 
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMapByKey(final Map<K, V> map, final SortingOrder sortingOrder) {
    Comparator<Map.Entry<K, V>> comparator = new Comparator<Entry<K,V>>() {
        public int compare(Entry<K, V> o1, Entry<K, V> o2) {
            return comparableCompare(o1.getKey(), o2.getKey(), sortingOrder);
        }
    };

    return sortMap(map, comparator);
}

/**
 * Sort a map by it's values.
 *  
 * @param sortingOrder {@link SortingOrder} enum specifying requested sorting order. 
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMapByValue(final Map<K, V> map, final SortingOrder sortingOrder) {
    Comparator<Map.Entry<K, V>> comparator = new Comparator<Entry<K,V>>() {
        public int compare(Entry<K, V> o1, Entry<K, V> o2) {
            return comparableCompare(o1.getValue(), o2.getValue(), sortingOrder);
        }
    };

    return sortMap(map, comparator);
}

@SuppressWarnings("unchecked")
private static <T> int comparableCompare(T o1, T o2, SortingOrder sortingOrder) {
    int compare = ((Comparable<T>)o1).compareTo(o2);

    switch (sortingOrder) {
    case ASCENDING:
        return compare;
    case DESCENDING:
        return (-1) * compare;
    }

    return 0;
}

/**
 * Sort a map by supplied comparator logic.
 *  
 * @return new instance of {@link LinkedHashMap} contained sorted entries of supplied map.
 * @author Maxim Veksler
 */
public static <K, V> LinkedHashMap<K, V> sortMap(final Map<K, V> map, final Comparator<Map.Entry<K, V>> comparator) {
    // Convert the map into a list of key,value pairs.
    List<Map.Entry<K, V>> mapEntries = new LinkedList<Map.Entry<K, V>>(map.entrySet());

    // Sort the converted list according to supplied comparator.
    Collections.sort(mapEntries, comparator);

    // Build a new ordered map, containing the same entries as the old map.  
    LinkedHashMap<K, V> result = new LinkedHashMap<K, V>(map.size() + (map.size() / 20));
    for(Map.Entry<K, V> entry : mapEntries) {
        // We iterate on the mapEntries list which is sorted by the comparator putting new entries into 
        // the targeted result which is a sorted map. 
        result.put(entry.getKey(), entry.getValue());
    }

    return result;
}

/**
 * Sorting order enum, specifying request result sort behavior.
 * @author Maxim Veksler
 *
 */
public static enum SortingOrder {
    /**
     * Resulting sort will be from smaller to biggest.
     */
    ASCENDING,
    /**
     * Resulting sort will be from biggest to smallest.
     */
    DESCENDING
}

তারপরে আবার সম্ভবত আরও ভাল সমাধান হ'ল org.apache.commons.collections.bidimap.TreeBidiMap
ম্যাক্সিমাম ভিক্সলার

4

এখানে একটি ওও সমাধান (অর্থাত্ staticপদ্ধতিগুলি ব্যবহার করে না ):

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class SortableValueMap<K, V extends Comparable<V>>
  extends LinkedHashMap<K, V> {
  public SortableValueMap() { }

  public SortableValueMap( Map<K, V> map ) {
    super( map );
  }

  public void sortByValue() {
    List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>( entrySet() );

    Collections.sort( list, new Comparator<Map.Entry<K, V>>() {
      public int compare( Map.Entry<K, V> entry1, Map.Entry<K, V> entry2 ) {
        return entry1.getValue().compareTo( entry2.getValue() );
      }
    });

    clear();

    for( Map.Entry<K, V> entry : list ) {
      put( entry.getKey(), entry.getValue() );
    }
  }

  private static void print( String text, Map<String, Double> map ) {
    System.out.println( text );

    for( String key : map.keySet() ) {
      System.out.println( "key/value: " + key + "/" + map.get( key ) );
    }
  }

  public static void main( String[] args ) {
    SortableValueMap<String, Double> map =
      new SortableValueMap<String, Double>();

    map.put( "A", 67.5 );
    map.put( "B", 99.5 );
    map.put( "C", 82.4 );
    map.put( "D", 42.0 );

    print( "Unsorted map", map );
    map.sortByValue();
    print( "Sorted map", map );
  }
}

এর দ্বারা পাবলিক ডোমেনে অনুদান দেওয়া হয়েছে।


4

আফিক সর্বাধিক পরিষ্কার উপায় মানকে মান অনুসারে বাছাইয়ের জন্য সংগ্রহগুলি ব্যবহার করছে:

Map<String, Long> map = new HashMap<String, Long>();
// populate with data to sort on Value
// use datastructure designed for sorting

Queue queue = new PriorityQueue( map.size(), new MapComparable() );
queue.addAll( map.entrySet() );

// get a sorted map
LinkedHashMap<String, Long> linkedMap = new LinkedHashMap<String, Long>();

for (Map.Entry<String, Long> entry; (entry = queue.poll())!=null;) {
    linkedMap.put(entry.getKey(), entry.getValue());
}

public static class MapComparable implements Comparator<Map.Entry<String, Long>>{

  public int compare(Entry<String, Long> e1, Entry<String, Long> e2) {
    return e1.getValue().compareTo(e2.getValue());
  }
}

4

সদৃশ মান রয়েছে এমন জোড়গুলির সাথে বাছাই করা মানচিত্রের জন্য কিছু সাধারণ পরিবর্তন। তুলনা পদ্ধতিতে (শ্রেণি মানকাম্পারেটর) মানগুলি সমান হয় যখন 0 না দেয় তবে 2 কীগুলির সাথে তুলনা করার ফলাফলটি ফিরে আসে। কীগুলি মানচিত্রে স্বতন্ত্র তাই আপনি সদৃশ মান রাখতে সফল হন (যা কী দ্বারা সাজাতে হয়)। সুতরাং উপরের উদাহরণটি এভাবে পরিবর্তিত হতে পারে:

    public int compare(Object a, Object b) {

        if((Double)base.get(a) < (Double)base.get(b)) {
          return 1;
        } else if((Double)base.get(a) == (Double)base.get(b)) {
          return ((String)a).compareTo((String)b);
        } else {
          return -1;
        }
      }
    }

4

নিশ্চিতভাবে স্টিফেনের সমাধানটি দুর্দান্ত, তবে যারা পেয়ারা ব্যবহার করতে পারবেন না তাদের জন্য:

মানচিত্র অনুসারে বাছাই করার জন্য আমার সমাধান এখানে's এই দ্রবণটি হ্যান্ডেলটি হ্যান্ডল করে যেখানে একই মান দ্বিগুণ হয় ...

// If you want to sort a map by value, and if there can be twice the same value:

// here is your original map
Map<String,Integer> mapToSortByValue = new HashMap<String, Integer>();
mapToSortByValue.put("A", 3);
mapToSortByValue.put("B", 1);
mapToSortByValue.put("C", 3);
mapToSortByValue.put("D", 5);
mapToSortByValue.put("E", -1);
mapToSortByValue.put("F", 1000);
mapToSortByValue.put("G", 79);
mapToSortByValue.put("H", 15);

// Sort all the map entries by value
Set<Map.Entry<String,Integer>> set = new TreeSet<Map.Entry<String,Integer>>(
        new Comparator<Map.Entry<String,Integer>>(){
            @Override
            public int compare(Map.Entry<String,Integer> obj1, Map.Entry<String,Integer> obj2) {
                Integer val1 = obj1.getValue();
                Integer val2 = obj2.getValue();
                // DUPLICATE VALUE CASE
                // If the values are equals, we can't return 0 because the 2 entries would be considered
                // as equals and one of them would be deleted (because we use a set, no duplicate, remember!)
                int compareValues = val1.compareTo(val2);
                if ( compareValues == 0 ) {
                    String key1 = obj1.getKey();
                    String key2 = obj2.getKey();
                    int compareKeys = key1.compareTo(key2);
                    if ( compareKeys == 0 ) {
                        // what you return here will tell us if you keep REAL KEY-VALUE duplicates in your set
                        // if you want to, do whatever you want but do not return 0 (but don't break the comparator contract!)
                        return 0;
                    }
                    return compareKeys;
                }
                return compareValues;
            }
        }
);
set.addAll(mapToSortByValue.entrySet());


// OK NOW OUR SET IS SORTED COOL!!!!

// And there's nothing more to do: the entries are sorted by value!
for ( Map.Entry<String,Integer> entry : set ) {
    System.out.println("Set entries: " + entry.getKey() + " -> " + entry.getValue());
}




// But if you add them to an hashmap
Map<String,Integer> myMap = new HashMap<String,Integer>();
// When iterating over the set the order is still good in the println...
for ( Map.Entry<String,Integer> entry : set ) {
    System.out.println("Added to result map entries: " + entry.getKey() + " " + entry.getValue());
    myMap.put(entry.getKey(), entry.getValue());
}

// But once they are in the hashmap, the order is not kept!
for ( Integer value : myMap.values() ) {
    System.out.println("Result map values: " + value);
}
// Also this way doesn't work:
// Logic because the entryset is a hashset for hashmaps and not a treeset
// (and even if it was a treeset, it would be on the keys only)
for ( Map.Entry<String,Integer> entry : myMap.entrySet() ) {
    System.out.println("Result map entries: " + entry.getKey() + " -> " + entry.getValue());
}


// CONCLUSION:
// If you want to iterate on a map ordered by value, you need to remember:
// 1) Maps are only sorted by keys, so you can't sort them directly by value
// 2) So you simply CAN'T return a map to a sortMapByValue function
// 3) You can't reverse the keys and the values because you have duplicate values
//    This also means you can't neither use Guava/Commons bidirectionnal treemaps or stuff like that

// SOLUTIONS
// So you can:
// 1) only sort the values which is easy, but you loose the key/value link (since you have duplicate values)
// 2) sort the map entries, but don't forget to handle the duplicate value case (like i did)
// 3) if you really need to return a map, use a LinkedHashMap which keep the insertion order

এক্সিকিউটিভ: http://www.ideone.com/dq3Lu

আউটপুট:

Set entries: E -> -1
Set entries: B -> 1
Set entries: A -> 3
Set entries: C -> 3
Set entries: D -> 5
Set entries: H -> 15
Set entries: G -> 79
Set entries: F -> 1000
Added to result map entries: E -1
Added to result map entries: B 1
Added to result map entries: A 3
Added to result map entries: C 3
Added to result map entries: D 5
Added to result map entries: H 15
Added to result map entries: G 79
Added to result map entries: F 1000
Result map values: 5
Result map values: -1
Result map values: 1000
Result map values: 79
Result map values: 3
Result map values: 1
Result map values: 3
Result map values: 15
Result map entries: D -> 5
Result map entries: E -> -1
Result map entries: F -> 1000
Result map entries: G -> 79
Result map entries: A -> 3
Result map entries: B -> 1
Result map entries: C -> 3
Result map entries: H -> 15

আশা করি এটি কিছু লোককে সহায়তা করবে


3

আপনার যদি ডুপ্লিকেট কী এবং কেবলমাত্র একটি ছোট সেট ডেটা (<1000) থাকে এবং আপনার কোডটি সম্পাদনা সমালোচনা না করে আপনি কেবল নিম্নলিখিতটি করতে পারেন:

Map<String,Integer> tempMap=new HashMap<String,Integer>(inputUnsortedMap);
LinkedHashMap<String,Integer> sortedOutputMap=new LinkedHashMap<String,Integer>();

for(int i=0;i<inputUnsortedMap.size();i++){
    Map.Entry<String,Integer> maxEntry=null;
    Integer maxValue=-1;
    for(Map.Entry<String,Integer> entry:tempMap.entrySet()){
        if(entry.getValue()>maxValue){
            maxValue=entry.getValue();
            maxEntry=entry;
        }
    }
    tempMap.remove(maxEntry.getKey());
    sortedOutputMap.put(maxEntry.getKey(),maxEntry.getValue());
}

ইনপুটসর্টম্যাপ কোডের ইনপুট।

পরিবর্তনশীল সাজানোআউটপুটম্যাপে পুনরাবৃত্তির সময় ডেঙ্কিং অর্ডে ডেটা থাকবে। অর্ডার পরিবর্তন করতে কেবল> বিবৃতির একটি <টিতে পরিবর্তন করুন।

দ্রুততম বাছাই নয় তবে কোনও অতিরিক্ত নির্ভরতা ছাড়াই কাজটি করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.