तीन 1-लाइन उत्तर ...
मैं ऐसा करने के लिए Google संग्रह अमरूद का उपयोग करूंगा - यदि आपके मूल्य हैं Comparable
तो आप उपयोग कर सकते हैं
valueComparator = Ordering.natural().onResultOf(Functions.forMap(map))
जो नक्शे के लिए एक फ़ंक्शन (ऑब्जेक्ट) बनाएगा [जो कि किसी भी कुंजी को इनपुट के रूप में लेता है, संबंधित मान लौटाता है], और फिर उन्हें [मूल्यों] के लिए प्राकृतिक (तुलनीय) आदेश लागू करें।
यदि वे तुलनीय नहीं हैं, तो आपको कुछ करने की आवश्यकता होगी
valueComparator = Ordering.from(comparator).onResultOf(Functions.forMap(map))
ये कुछ छँटाई के बाद ट्रीपेज़ (जैसे Ordering
फैली हुई Comparator
), या लिंक्डहाशपॉइंट पर लागू हो सकते हैं
नायब : यदि आप ट्रीपाइप का उपयोग करने जा रहे हैं, तो याद रखें कि यदि एक तुलना == 0 है, तो आइटम पहले से ही सूची में है (जो कि आपके समान मानों के समान होने पर भी होगा)। इसे कम करने के लिए, आप अपनी कुंजी को तुलनित्र में जोड़ सकते हैं जैसे (यह मानते हुए कि आपकी कुंजी और मान हैं Comparable
):
valueComparator = Ordering.natural().onResultOf(Functions.forMap(map)).compound(Ordering.natural())
= कुंजी द्वारा मैप किए गए मान के लिए प्राकृतिक आदेश लागू करें, और कुंजी के प्राकृतिक क्रम के साथ यौगिक करें
ध्यान दें कि यह तब भी काम नहीं करेगा यदि आपकी चाबियाँ 0 से तुलना करती हैं, लेकिन यह अधिकांश comparable
मदों के लिए पर्याप्त होना चाहिए (जैसा कि hashCode
, equals
और compareTo
अक्सर सिंक में है ...)
आदेश देखें .onResultOf () और Functions.forMap () ।
कार्यान्वयन
इसलिए अब जब हमें एक तुलनित्र मिल गया है जो हम चाहते हैं, हमें उससे एक परिणाम प्राप्त करने की आवश्यकता है।
map = ImmutableSortedMap.copyOf(myOriginalMap, valueComparator);
अब यह सबसे अधिक संभावना काम करेगा, लेकिन:
- पूरा किया गया नक्शा दिया जाना चाहिए
- ऊपर की तुलना करने वालों की कोशिश न करें
TreeMap
; कोई सम्मिलित कुंजी की तुलना करने की कोशिश करने का कोई मतलब नहीं है जब पुट के बाद तक इसका कोई मूल्य नहीं होता है, अर्थात, यह वास्तव में तेजी से टूट जाएगा
बिंदु 1 मेरे लिए एक सौदा तोड़ने वाला है; Google संग्रह अविश्वसनीय रूप से आलसी है (जो अच्छा है: आप एक पल में हर ऑपरेशन को बहुत अधिक कर सकते हैं; वास्तविक काम तब किया जाता है जब आप परिणाम का उपयोग करना शुरू करते हैं), और इसके लिए एक पूरे नक्शे की प्रतिलिपि बनाने की आवश्यकता होती है !
"मानों द्वारा पूर्ण उत्तर / लाइव छाँटे गए मानचित्र
हालांकि चिंता मत करो; यदि आप इस तरह से "लाइव" नक्शा होने के साथ पर्याप्त रूप से रोमांचित थे, तो आप उपरोक्त मुद्दों के एक नहीं बल्कि दोनों (!) को हल कर सकते हैं:
नोट: यह जून 2012 में काफी बदल गया है - पिछला कोड कभी काम नहीं कर सकता: TreeMap.get()
-> compare()
और compare()
-> के बीच एक अनंत लूप बनाए बिना मानों को देखने के लिए एक आंतरिक हैशपॉप की आवश्यकता होती है।get()
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));
List<Map.Entry<...>> list =new LinkedList(map.entrySet())
औरCollections.sort ....
यह इस तरह से।