জাভাতে কী অনুসারে মানচিত্রের মানগুলি বাছাই করবেন কীভাবে?


361

আমার কাছে একটি মানচিত্র রয়েছে যা কী এবং মান উভয়ের জন্য স্ট্রিং রয়েছে।

ডেটা নীচের মত:

"প্রশ্ন 1", "1"
"প্রশ্ন9", "1"
"প্রশ্ন 2", "4"
"প্রশ্ন 5", "2"

আমি মানচিত্রগুলি এর কীগুলির উপর ভিত্তি করে সাজিয়ে রাখতে চাই। সুতরাং, শেষ পর্যন্ত, আমি question1, question2, question3.... এবং আরও কিছু করব।


শেষ পর্যন্ত, আমি এই মানচিত্রটি থেকে দুটি স্ট্রিং নেওয়ার চেষ্টা করছি।

  • প্রথম স্ট্রিং: প্রশ্নগুলি (ক্রম 1 .. 10)
  • দ্বিতীয় স্ট্রিং: উত্তর (প্রশ্নের একই ক্রমে)

এই মুহূর্তে আমার কাছে নিম্নলিখিতগুলি রয়েছে:

Iterator it = paramMap.entrySet().iterator();
while (it.hasNext()) {
    Map.Entry pairs = (Map.Entry) it.next();
    questionAnswers += pairs.getKey() + ",";
}

এটি আমার কাছে প্রশ্নগুলিকে একটি স্ট্রিংয়ে পেয়েছে তবে সেগুলি ক্রমযুক্ত নয়।

উত্তর:


612

সংক্ষিপ্ত উত্তর

ব্যবহার ক TreeMap। এটি ঠিক এটির জন্য।

যদি এই মানচিত্রটি আপনাকে দেওয়া হয় এবং আপনি প্রকারটি নির্ধারণ করতে না পারেন তবে আপনি নিম্নলিখিতটি করতে পারেন:

SortedSet<String> keys = new TreeSet<>(map.keySet());
for (String key : keys) { 
   String value = map.get(key);
   // do something
}

এটি কীগুলির প্রাকৃতিক ক্রমে মানচিত্র জুড়ে পুনরাবৃত্তি হবে।


দীর্ঘ উত্তর

প্রযুক্তিগতভাবে, আপনি প্রয়োগকারী যা কিছু ব্যবহার করতে পারেন SortedMap, তবে বিরল ক্ষেত্রে ব্যতীত এটির পরিমাণ TreeMapঠিক তেমনই একটি Mapবাস্তবায়ন ব্যবহারের সমান HashMap

আপনার কীগুলি এমন জটিল ধরণের যা তুলনামূলক প্রয়োগ করে না বা আপনি তখন প্রাকৃতিক ক্রমটি ব্যবহার করতে চান না TreeMapএবং TreeSetঅতিরিক্ত কন্সট্রাক্টর রয়েছে যা আপনাকে একটিতে পাস করতে দেয় Comparator:

// placed inline for the demonstration, but doesn't have to be a lambda expression
Comparator<Foo> comparator = (Foo o1, Foo o2) -> {
        ...
    }

SortedSet<Foo> keys = new TreeSet<>(comparator);
keys.addAll(map.keySet());

যখন একটি ব্যবহার মনে রাখুন TreeMapবা TreeSetএটা থেকে আলাদা কর্মক্ষমতা বৈশিষ্ট্য আছে করবে HashMapবা HashSet। মোটামুটি কথা বলার ক্রিয়াকলাপগুলি যা কোনও উপাদান সন্ধান করে বা সন্নিবেশ করায় তা ও (1) থেকে ও (লগ (এন)) এ যাবে

একটি HashMap, 1000 আইটেম থেকে 10,000 থেকে সরানোর সত্যিই একটি উপাদান অনুসন্ধান করতে আপনার সময় প্রভাবিত করে না, কিন্তু একটি জন্য TreeMapলুকআপ সময় 3 বার ধীর (অভিমানী লগিন হতে হবে 2 )। 1000 থেকে 100,000 এ স্থানান্তর প্রতিটি উপাদান দেখার জন্য প্রায় 6 গুণ ধীর হয়ে যাবে।


আমি ট্রিম্যাপ ব্যবহার এবং দৈর্ঘ্যের উপর ভিত্তি করে স্ট্রিং কীগুলি বাছাই করার চেষ্টা করছি। আমি দেখতে পেয়েছি যে আমি বেমানান পুনরুদ্ধারের ফলাফল পাচ্ছি। দৃশ্যত কারণ TreeMap 0 এর তুলনা করার ফলাফলটিকে "সমান" হিসাবে বিবেচনা করে? এই ক্ষেত্রে এটি কীভাবে ব্যবহার করবেন তা নিশ্চিত নন।
মার্ক

1
CompTTo () এর ফলাফল 'সমান' is আপনি যদি একটি তুলনামূলক লিখছেন যা স্ট্রিং দৈর্ঘ্যের ভিত্তিতে বাছাই করে থাকে তবে আপনাকে কোন স্ট্রিং দীর্ঘ হবে তার ভিত্তিতে একটি ধনাত্মক বা নেতিবাচক মান প্রদান করতে হবে এবং উভয় স্ট্রিং একই দৈর্ঘ্যের হলে কেবল 0 প্রদান করতে হবে। যদি a এবং b স্ট্রিং হয় তবে আপনি এগুলি করতে পারেন যেমন - রিটার্ন a.leth () - b.leth () '(অথবা মানগুলি যদি অন্য দিকে বাছাই করতে চান তবে বিপরীত করুন)।
ঝেরিকো

হ্যালো ছেলেরা, যদি তিনি মানচিত্রে কীগুলি দ্বারা অর্ডার করতে চান, যা এখানে 1,2,3,4, সন্নিবেশ আদেশ কী .... আমরা কেন লিঙ্কডহ্যাশসেটটি ব্যবহার করছি না? আমরা কেবল একের পর এক প্রশ্ন রেখেছি এবং এটি সন্নিবেশের ক্রম অনুসারে অর্ডার করা হচ্ছে। কেউ আমাকে এই সাহায্য করতে পারেন?
করলি

@ ক্যারোলি লিংকডহ্যাশসেট উপাদানগুলি যেভাবে sertedোকিয়েছে সেগুলি পুনরুদ্ধারে কাজ করবে। ওপি যা চায় তা হ'ল সন্নিবেশনের আদেশ নির্বিশেষে কিছু পূর্বনির্ধারিত ক্রমানুসারে উপাদানগুলি পুনরুদ্ধার করা।
ডেভিড বেরি

@ ক্রিকেট_007 কোডটি ইতিমধ্যে বাছাই করা হয়নি এমন মানচিত্রের কীগুলি কীভাবে পুনরায় পুনরাবৃত্তি করতে হবে তা প্রদর্শন করছে।
ঝাড়িকো

137

ধরে নেওয়া ট্রিম্যাপ আপনার পক্ষে ভাল নয় (এবং ধরে নিই যে আপনি জেনেরিক ব্যবহার করতে পারবেন না):

List sortedKeys=new ArrayList(yourMap.keySet());
Collections.sort(sortedKeys);
// Do what you need with sortedKeys.

3
ধন্যবাদ! আমার চাবিগুলি জটিল ধরণের ছিল বলে আমার এ জাতীয় কিছু করা দরকার।
রস হ্যামব্রিক

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

55

এটি ব্যবহার করে TreeMapআপনি মানচিত্রটি বাছাই করতে পারেন।

Map<String, String> map = new HashMap<>();        
Map<String, String> treeMap = new TreeMap<>(map);
for (String str : treeMap.keySet()) {
    System.out.println(str);
}

1
মানচিত্র <স্ট্রিং, তালিকা <স্ট্রিং>> ট্রি ম্যাপ = নতুন ট্রিম্যাপ <স্ট্রিং, তালিকা <স্ট্রিং>> (মুদ্রণ হ্যাশম্যাপ); (স্ট্রিং স্ট্রিং: ট্রিটম্যাপ.কিসেট ())। System.out.println (+ + "" + ট্রিটম্যাপ.জেট (স্ট্র)); }
বিক্রমভি

37

একটি ট্রিম্যাপ ব্যবহার করুন !


31
+1 - ঝেরিকো, জনকে পরাস্ত করতে যথেষ্ট তত্পর নয়, তবে এখনও বেশ ভাল। 8)
ডাফাইমো

আমি জাভা জানি না :-( এই 100% কাজ করে ভয়ঙ্কর সমাধান তুলনায় অনেক বেশি সহজ আমি নিয়ে এসেছেন।
peterchaula

36

আপনার যদি ইতিমধ্যে কোনও মানচিত্র থাকে এবং কীগুলি বাছাই করতে চান তবে সহজভাবে ব্যবহার করুন:

Map<String, String> treeMap = new TreeMap<String, String>(yourMap);

একটি সম্পূর্ণ কাজের উদাহরণ:

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

class SortOnKey {

public static void main(String[] args) {
   HashMap<String,String> hm = new HashMap<String,String>();
   hm.put("3","three");
   hm.put("1","one");
   hm.put("4","four");
   hm.put("2","two");
   printMap(hm);
   Map<String, String> treeMap = new TreeMap<String, String>(hm);
   printMap(treeMap);
}//main

public static void printMap(Map<String,String> map) {
    Set s = map.entrySet();
    Iterator it = s.iterator();
    while ( it.hasNext() ) {
       Map.Entry entry = (Map.Entry) it.next();
       String key = (String) entry.getKey();
       String value = (String) entry.getValue();
       System.out.println(key + " => " + value);
    }//while
    System.out.println("========================");
}//printMap

}//class

36

শুধু ট্রিম্যাপ ব্যবহার করুন

new TreeMap<String, String>(unsortMap);

সচেতন থাকুন যে ট্রি ম্যাপটি তার 'কী'-এর প্রাকৃতিক ক্রম অনুসারে বাছাই করা হয়


19

প্রদত্ত আপনি ব্যবহার করতে পারবেন না TreeMap, জাভা 8 এ আমরা টোম্যাপ () পদ্ধতিটি ব্যবহার করতে পারি যাতে Collectorsনিম্নলিখিত প্যারামিটারগুলি লাগে:

  • keymapper : কীগুলি উত্পাদন করতে ম্যাপিং ফাংশন
  • valuemapper : মান উত্পাদন করতে ম্যাপিং ফাংশন
  • mergeFunction : একটি একত্রীকরণ ফাংশন, একই কী যুক্ত মানের মধ্যে সমাধান দুর্ঘটনায় করতে ব্যবহৃত
  • ম্যাপসপ্লায়ার : একটি ফাংশন যা একটি নতুন, খালি মানচিত্র দেয় যার মধ্যে ফলাফল .োকানো হবে।

জাভা 8 উদাহরণ

Map<String,String> sample = new HashMap<>();  // push some values to map  
Map<String, String> newMapSortedByKey = sample.entrySet().stream()
                    .sorted(Map.Entry.<String,String>comparingByKey().reversed())
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
Map<String, String> newMapSortedByValue = sample.entrySet().stream()
                        .sorted(Map.Entry.<String,String>comparingByValue().reversed())
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1,e2) -> e1, LinkedHashMap::new));

আমরা কাস্টম তুলকটি ব্যবহার করতে এবং কীগুলির উপর ভিত্তি করে সাজানোর জন্য উদাহরণটি পরিবর্তন করতে পারি:

Map<String, String> newMapSortedByKey = sample.entrySet().stream()
                .sorted((e1,e2) -> e1.getKey().compareTo(e2.getKey()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1,e2) -> e1, LinkedHashMap::new));

শুধুমাত্র এপিআই 24 এবং এর চেয়ে বেশি এর সাথে অ্যান্ড্রয়েডে কাজ করে।
টিনা

9

জাভা 8 ব্যবহার করে :

Map<String, Integer> sortedMap = unsortMap.entrySet().stream()
            .sorted(Map.Entry.comparingByKey())
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                    (oldValue, newValue) -> oldValue, LinkedHashMap::new));

5

এই কোড একটি মূল মান মানচিত্র উভয় অর্ডারে বা আরোহণ এবং উতরাই বাছাই করতে পারে।

<K, V extends Comparable<V>> Map<K, V> sortByValues
     (final Map<K, V> map, int ascending)
{
     Comparator<K> valueComparator =  new Comparator<K>() {         
        private int ascending;
        public int compare(K k1, K k2) {
            int compare = map.get(k2).compareTo(map.get(k1));
            if (compare == 0) return 1;
            else return ascending*compare;
        }
        public Comparator<K> setParam(int ascending)
        {
            this.ascending = ascending;
            return this;
        }
    }.setParam(ascending);

    Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
    sortedByValues.putAll(map);
    return sortedByValues;
}

উদাহরণ হিসাবে:

Map<Integer,Double> recommWarrVals = new HashMap<Integer,Double>();
recommWarrVals = sortByValues(recommWarrVals, 1);  // Ascending order
recommWarrVals = sortByValues(recommWarrVals,-1);  // Descending order

5

জাভা 8 এ

Map<K, V>কী অনুসারে বাছাই করতে , কীগুলিকে একটিতে রেখে List<K>:

List<K> result = map.keySet().stream().sorted().collect(Collectors.toList());

Map<K, V>কী অনুসারে বাছাই করার জন্য, এগুলিতে একটি এন্ট্রি রেখে List<Map.Entry<K, V>>:

List<Map.Entry<K, V>> result =
    map.entrySet()
       .stream()
       .sorted(Map.Entry.comparingByKey())
       .collect(Collectors.toList());

সর্বশেষে তবে সর্বনিম্ন নয়: লোকাল-সংবেদনশীল পদ্ধতিতে স্ট্রিং সাজানোর জন্য - একটি কোলাটার (তুলনামূলক) শ্রেণি ব্যবহার করুন:

Collator collator = Collator.getInstance(Locale.US);
collator.setStrength(Collator.PRIMARY); // case insensitive collator

List<Map.Entry<String, String>> result =
    map.entrySet()
       .stream()
       .sorted(Map.Entry.comparingByKey(collator))
       .collect(Collectors.toList());

1
List<String> list = new ArrayList<String>();
Map<String, String> map = new HashMap<String, String>();
for (String str : map.keySet()) {
 list.add(str);
}
Collections.sort(list);
for (String str : list) {
 System.out.println(str);
}

1

জাভা 8 এ আপনি .stream ()। সাজানো () ব্যবহার করতে পারেন:

myMap.keySet().stream().sorted().forEach(key -> {
        String value = myMap.get(key);

        System.out.println("key: " + key);
        System.out.println("value: " + value);
    }
);

0

অ্যারে.সোর্ট পদ্ধতি ব্যবহার করে আমরা কীটি বাছাই করতে পারি।

Map<String, String> map = new HashMap<String, String>();
Object[] objArr = new Object[map.size()];
for (int i = 0; i < map.size(); i++) {
objArr[i] = map.get(i);
}
Arrays.sort(objArr);
for (Object str : objArr) {
System.out.println(str);
}

এটি মান অনুসারে বাছাই করা হচ্ছে কী নয়।
রাজ

0

শুধু আপনি যদি একটি ব্যবহার করতে চান না TreeMap

public static Map<Integer, Integer> sortByKey(Map<Integer, Integer> map) {
    List<Map.Entry<Integer, Integer>> list = new ArrayList<>(map.entrySet());
    list.sort(Comparator.comparingInt(Map.Entry::getKey));
    Map<Integer, Integer> sortedMap = new HashMap<>();
    list.forEach(sortedMap.put(e.getKey(), e.getValue()));
    return sortedMap;
}

এছাড়াও, ইন-কেস আপনি ভিত্তিতে আপনার মানচিত্রে সাজাতে চেয়েছিলেন valuesমাত্র পরিবর্তন Map.Entry::getKeyকরতেMap.Entry::getValue


এটি আমার পর্যালোচনা লগে উঠে এসেছে। কেউ ভেরিয়েবলের নামের সাথে কিছু ত্রুটি সমাধানের চেষ্টা করেছিলেন (তবে ব্যর্থ হয়েছেন)। সুতরাং, আমি এগুলি সঠিকভাবে স্থির করেছি, তবে এই উত্তরটি মূলত ভুল। আপনি যে অর্থে হ্যাশম্যাপে মান যুক্ত করবেন তা অপ্রাসঙ্গিক। মানচিত্রের অর্ডার নেই। stackoverflow.com/questions/10710193/...
aepryus
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.