एक ही कुंजी के तहत कई मानों के साथ हाशप


199

क्या हमारे लिए एक कुंजी और दो मूल्यों के साथ हाशप को लागू करना संभव है। जैसे हैशपॉप?

कृपया मेरी मदद करें, यह भी बताकर (अगर कोई रास्ता नहीं है) कुंजी के रूप में एक के साथ तीन मूल्यों के भंडारण को लागू करने का कोई अन्य तरीका?



धन्यवाद दोस्तों ... लेकिन मेरे पास कुछ हदें हैं MultiHashMap
vidhya

जवाबों:


266

आप ऐसा कर सकते हैं:

  1. उस मानचित्र का उपयोग करें जिसमें मूल्य के रूप में एक सूची है। Map<KeyType, List<ValueType>>
  2. मानचित्र में इस आवरण के नए रैपर क्लास और स्थान इंस्टेंसेस बनाएं। Map<KeyType, WrapperType>
  3. कक्षा की तरह एक टपल का उपयोग करें (बहुत सारे रैपर बनाने से बचाता है)। Map<KeyType, Tuple<Value1Type, Value2Type>>
  4. अगल-बगल के मानचित्रों का उपयोग करें।

उदाहरण

1. मूल्य के रूप में सूची के साथ नक्शा

// create our map
Map<String, List<Person>> peopleByForename = new HashMap<>();    

// populate it
List<Person> people = new ArrayList<>();
people.add(new Person("Bob Smith"));
people.add(new Person("Bob Jones"));
peopleByForename.put("Bob", people);

// read from it
List<Person> bobs = peopleByForename["Bob"];
Person bob1 = bobs[0];
Person bob2 = bobs[1];

इस दृष्टिकोण के साथ नुकसान यह है कि सूची बिल्कुल दो मूल्यों के लिए बाध्य नहीं है।

2. रैपर क्लास का उपयोग करना

// define our wrapper
class Wrapper {
    public Wrapper(Person person1, Person person2) {
       this.person1 = person1;
       this.person2 = person2;
    }

    public Person getPerson1 { return this.person1; }
    public Person getPerson2 { return this.person2; }

    private Person person1;
    private Person person2;
}

// create our map
Map<String, Wrapper> peopleByForename = new HashMap<>();

// populate it
Wrapper people = new Wrapper();
peopleByForename.put("Bob", new Wrapper(new Person("Bob Smith"),
                                        new Person("Bob Jones"));

// read from it
Wrapper bobs = peopleByForename.get("Bob");
Person bob1 = bobs.getPerson1;
Person bob2 = bobs.getPerson2;

इस दृष्टिकोण का नुकसान यह है कि आपको इन सभी सरल कंटेनर वर्गों के लिए बहुत सारे बॉयलर-प्लेट कोड लिखना होगा।

3. एक नल का उपयोग करना

// you'll have to write or download a Tuple class in Java, (.NET ships with one)

// create our map
Map<String, Tuple2<Person, Person> peopleByForename = new HashMap<>();

// populate it
peopleByForename.put("Bob", new Tuple2(new Person("Bob Smith",
                                       new Person("Bob Jones"));

// read from it
Tuple<Person, Person> bobs = peopleByForename["Bob"];
Person bob1 = bobs.Item1;
Person bob2 = bobs.Item2;

मेरी राय में यह सबसे अच्छा समाधान है।

4. कई नक्शे

// create our maps
Map<String, Person> firstPersonByForename = new HashMap<>();
Map<String, Person> secondPersonByForename = new HashMap<>();

// populate them
firstPersonByForename.put("Bob", new Person("Bob Smith"));
secondPersonByForename.put("Bob", new Person("Bob Jones"));

// read from them
Person bob1 = firstPersonByForename["Bob"];
Person bob2 = secondPersonByForename["Bob"];

इस समाधान का नुकसान यह है कि यह स्पष्ट नहीं है कि दो नक्शे संबंधित हैं, एक प्रोग्रामेटिक त्रुटि दो मानचित्रों को सिंक से बाहर निकलती देख सकती है।


हाय पॉल ... यू इसे थोड़ा और स्पष्ट कर सकता है ... एक उदाहरण से ...?
विंध्य

@vidhya: जो विशेष रूप से आपकी समस्या पर फिट बैठता है? क्या आपकी मल्टिपल वस्तुएं एक ही प्रकार या अलग हैं?
पॉल रूएन

उदाहरण वास्तव में महान होगा।
Xonatron

@Paul, # 3 के लिए कोई भी सरल उदाहरण कोड Map<KeyType, Tuple<Value1Type, Value2Type>>
जोर्डर कमल

@CoolMind मुझे यकीन है कि लोग गलतियों के आसपास अपना काम कर सकते हैं: या आप शायद उन्हें सही कर सकते हैं?
पॉल रुआन डिक

61

नहीं, सिर्फ एक के रूप में नहीं HashMap। आपको मूल रूप HashMapसे एक कुंजी से मूल्यों के संग्रह की आवश्यकता होगी ।

यदि आप बाहरी पुस्तकालयों का उपयोग करने के लिए खुश हैं, तो अमरूद का इस Multimapतरह के कार्यान्वयन के साथ बिल्कुल यही अवधारणा है ArrayListMultimapऔर HashMultimap


@ जॉन, क्या आप ओपी द्वारा पूछे गए उपरोक्त प्रश्न के लिए जावा में witha को काम करने का उदाहरण प्रदान कर सकते हैं। यदि आप इसे पोस्ट कर सकते हैं तो इसकी सराहना की जाएगी
दीपक

2
@ दीपक: अमरूद के उदाहरणों की खोज करें और आपको नमूना कोड मिलेगा।
जॉन स्कीट

1
@ दीपक: मूल रूप से आप कुछ ArrayListMultimapअपने जैसा बनायेंगे ... या बस एक HashMap<String, List<Integer>>या जो भी उपयोग करें । मूल रूप से पहली बार एक मूल्य जोड़े जाने पर आपको किसी भी समय एक खाली सूची बनाने की आवश्यकता होगी।
जॉन स्कीट

1
क्या आपके पास काम करने का उदाहरण हैHashMap<String, List<Integer>>
दीपक

9
@Deepak: मेरा सुझाव है कि आप स्वयं एक उदाहरण बनाने की कोशिश करें, और यदि आप अटक जाते हैं, तो कोड सहित एक प्रश्न पूछें जहाँ तक आपको मिला है। आप इस तरह से बहुत कुछ सीखेंगे।
जॉन स्कीट

23

एक और अच्छा विकल्प है Apache Commons से MultiValuedMap का उपयोग करना । विशेष कार्यान्वयन के लिए पृष्ठ के शीर्ष पर स्थित सभी ज्ञात कार्यान्वयन कक्षाओं पर एक नज़र डालें ।

उदाहरण:

HashMap<K, ArrayList<String>> map = new HashMap<K, ArrayList<String>>()

के साथ प्रतिस्थापित किया जा सकता है

MultiValuedMap<K, String> map = new MultiValuedHashMap<K, String>();

इसलिए,

map.put(key, "A");
map.put(key, "B");
map.put(key, "C");

Collection<String> coll = map.get(key);

coll"A", "B" और "C" वाले संग्रह में परिणाम होगा ।


13

Multimapअमरूद-पुस्तकालयों और इसके कार्यान्वयन पर एक नज़र डालें -HashMultimap

एक मानचित्र के समान एक संग्रह, लेकिन जो एक कुंजी के साथ कई मूल्यों को जोड़ सकता है। यदि आप पुट (K, V) को दो बार कहते हैं, तो एक ही कुंजी लेकिन अलग-अलग मानों के साथ, मल्टीमैप में कुंजी से दोनों मानों की मैपिंग होती है।


7

मैं Map<KeyType, Object[]>एक मानचित्र में एक कुंजी के साथ कई मूल्यों को जोड़ने के लिए उपयोग करता हूं । इस तरह, मैं एक कुंजी से जुड़े विभिन्न प्रकारों के कई मूल्यों को संग्रहीत कर सकता हूं। आपको ऑब्जेक्ट [] से डालने और पुनः प्राप्त करने के उचित क्रम को बनाए रखते हुए ध्यान रखना होगा।

उदाहरण: विचार करें, हम छात्र जानकारी संग्रहीत करना चाहते हैं। कुंजी आईडी है, जबकि हम छात्र से संबंधित नाम, पता और ईमेल संग्रहीत करना चाहते हैं।

       //To make entry into Map
        Map<Integer, String[]> studenMap = new HashMap<Integer, String[]>();
        String[] studentInformationArray = new String[]{"name", "address", "email"};
        int studenId = 1;
        studenMap.put(studenId, studentInformationArray);

        //To retrieve values from Map
        String name = studenMap.get(studenId)[1];
        String address = studenMap.get(studenId)[2];
        String email = studenMap.get(studenId)[3];

1
मेरे लिए यह सबसे अच्छा जवाब है। यह सरल, अधिक संक्षिप्त और कम सार है।
मोरे


4

बस रिकॉर्ड के लिए, शुद्ध JDK8 समाधान Map::computeविधि का उपयोग करना होगा :

map.compute(key, (s, strings) -> strings == null ? new ArrayList<>() : strings).add(value);

जैसे कि

public static void main(String[] args) {
    Map<String, List<String>> map = new HashMap<>();

    put(map, "first", "hello");
    put(map, "first", "foo");
    put(map, "bar", "foo");
    put(map, "first", "hello");

    map.forEach((s, strings) -> {
        System.out.print(s + ": ");
        System.out.println(strings.stream().collect(Collectors.joining(", ")));
    });
}

private static <KEY, VALUE> void put(Map<KEY, List<VALUE>> map, KEY key, VALUE value) {
    map.compute(key, (s, strings) -> strings == null ? new ArrayList<>() : strings).add(value);
}

आउटपुट के साथ:

bar: foo
first: hello, foo, hello

ध्यान दें कि यदि कई थ्रेड्स इस डेटा संरचना तक पहुँच प्राप्त करते हैं, ConcurrentHashMapऔर CopyOnWriteArrayListउदाहरण के लिए स्थिरता का उपयोग किया जाना चाहिए।


इसका उपयोग करना बेहतर है computeIfAbsentmap.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
सक 102929

3

यदि आप स्प्रिंग फ्रेमवर्क का उपयोग करते हैं । नहीं है: org.springframework.util.MultiValueMap

अचूक बहु मूल्य मानचित्र बनाने के लिए:

Map<String,List<String>> map = ...
MultiValueMap<String, String> multiValueMap = CollectionUtils.toMultiValueMap(map);

या उपयोग करें org.springframework.util.LinkedMultiValueMap


2

हां और ना। समाधान आपके मानों के लिए एक आवरण क्लैस का निर्माण करना है जिसमें 2 (3, या अधिक) मान शामिल हैं जो आपकी कुंजी के अनुरूप हैं।



2

Google संग्रह लाइब्रेरी का उपयोग करने का सबसे आसान तरीका होगा:

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

public class Test {

    public static void main(final String[] args) {

        // multimap can handle one key with a list of values
        final Multimap<String, String> cars = ArrayListMultimap.create();
        cars.put("Nissan", "Qashqai");
        cars.put("Nissan", "Juke");
        cars.put("Bmw", "M3");
        cars.put("Bmw", "330E");
        cars.put("Bmw", "X6");
        cars.put("Bmw", "X5");

        cars.get("Bmw").forEach(System.out::println);

        // It will print the:
        // M3
        // 330E
        // X6
        // X5
    }

}

मावेन लिंक: https://mvnrepository.com/artifact/com.google.collections/google-collections/1.0-rc2

इस पर अधिक: http://tomjefferys.blogspot.be/2011/09/multimaps-google-guava.html


1
String key= "services_servicename"

ArrayList<String> data;

for(int i = 0; i lessthen data.size(); i++) {
    HashMap<String, String> servicesNameHashmap = new HashMap<String, String>();
    servicesNameHashmap.put(key,data.get(i).getServiceName());
    mServiceNameArray.add(i,servicesNameHashmap);
}

मुझे सर्वश्रेष्ठ परिणाम मिले हैं।

आपको बस नया HashMapजैसा बनाना है

HashMap<String, String> servicesNameHashmap = new HashMap<String, String>();

तुम्हारे forपाश में। इसका समान कुंजी और कई मानों जैसा प्रभाव होगा।


1
 import java.io.*;
 import java.util.*;

 import com.google.common.collect.*;

 class finTech{
public static void main(String args[]){
       Multimap<String, String> multimap = ArrayListMultimap.create();
       multimap.put("1","11");
       multimap.put("1","14");
       multimap.put("1","12");
       multimap.put("1","13");
       multimap.put("11","111");
       multimap.put("12","121");
        System.out.println(multimap);
        System.out.println(multimap.get("11"));
   }                                                                                            
 }                                                                    

आउटपुट:

     {"1"=["11","12","13","14"],"11"=["111"],"12"=["121"]}

      ["111"]

यह यूटिलिटी फंक्शंस के लिए Google-Guava लाइब्रेरी है। यह आवश्यक उपाय है।


यह एक वैध समाधान है और मैंने कई मौकों पर इस दृष्टिकोण का उपयोग किया है।
लेटोवियनका

हाँ, यह काम कर रहा है लेकिन यह डेटा दिखा रहा है [] मैं उन वस्तुओं को एक-एक करके चाहता हूं कि कैसे प्राप्त करें कि pls यहां फंस गए
सुनील चौधरी

0

मैं पॉल की टिप्पणी पर कोई उत्तर नहीं दे सका, इसलिए मैं यहां विधा के लिए नई टिप्पणी कर रहा हूं:

रैपर उन SuperClassदो वर्गों के लिए होगा जो हम मूल्य के रूप में संग्रहीत करना चाहते हैं।

और आवरण वर्ग के अंदर, हम संघों को दो वर्ग वस्तुओं के लिए उदाहरण चर वस्तुओं के रूप में रख सकते हैं।

जैसे

class MyWrapper {

 Class1 class1obj = new Class1();
 Class2 class2obj = new Class2();
...
}

और हाशप में हम इस तरह से डाल सकते हैं,

Map<KeyObject, WrapperObject> 

WrapperObj में वर्ग चर होंगे:class1Obj, class2Obj


0

आप इसे अंतर्निहित रूप से कर सकते हैं।

// Create the map. There is no restriction to the size that the array String can have
HashMap<Integer, String[]> map = new HashMap<Integer, String[]>();

//initialize a key chosing the array of String you want for your values
map.put(1, new String[] { "name1", "name2" });

//edit value of a key
map.get(1)[0] = "othername";

यह बहुत ही सरल और प्रभावी है। यदि आप अलग-अलग वर्गों के मान चाहते हैं, तो आप निम्न कार्य कर सकते हैं:

HashMap<Integer, Object[]> map = new HashMap<Integer, Object[]>();

0

एक पहचान हाशपॅम का उपयोग करके किया जा सकता है, इस शर्त के अधीन कि कुंजी तुलना == ऑपरेटर द्वारा की जाएगी और न के बराबर ()।


0

मैं एक अलग वर्ग बनाने के बिना किसी भी संख्या में चर को संग्रहीत करने के लिए निम्नलिखित को प्राथमिकता देता हूं।

final public static Map<String, Map<String, Float>> myMap    = new HashMap<String, Map<String, Float>>();

0

मैं तो बस उद्देश्यपूर्ण सी में एक डेटा शब्दकोश के साथ ऐसा करने के लिए उपयोग किया जाता हूं। एंड्रॉइड के लिए जावा में एक समान परिणाम प्राप्त करना कठिन था। मैंने एक कस्टम क्लास का निर्माण किया, और फिर अपनी कस्टम क्लास का एक हैशमैप किया।

public class Test1 {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.addview);

//create the datastring
    HashMap<Integer, myClass> hm = new HashMap<Integer, myClass>();
    hm.put(1, new myClass("Car", "Small", 3000));
    hm.put(2, new myClass("Truck", "Large", 4000));
    hm.put(3, new myClass("Motorcycle", "Small", 1000));

//pull the datastring back for a specific item.
//also can edit the data using the set methods.  this just shows getting it for display.
    myClass test1 = hm.get(1);
    String testitem = test1.getItem();
    int testprice = test1.getPrice();
    Log.i("Class Info Example",testitem+Integer.toString(testprice));
}
}

//custom class.  You could make it public to use on several activities, or just include in the activity if using only here
class myClass{
    private String item;
    private String type;
    private int price;

    public myClass(String itm, String ty, int pr){
        this.item = itm;
        this.price = pr;
        this.type = ty;
    }

    public String getItem() {
        return item;
    }

    public void setItem(String item) {
        this.item = item;
    }

    public String getType() {
        return item;
    }

    public void setType(String type) {
        this.type = type;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

}

0

हम कई कुंजी या मान रखने के लिए एक वर्ग बना सकते हैं और इस वर्ग की वस्तु को मानचित्र में एक पैरामीटर के रूप में उपयोग किया जा सकता है। आप https://stackoverflow.com/a/44181931/8065321 का उल्लेख कर सकते हैं


0

जावा कलेक्टर का उपयोग करना

// Group employees by department
Map<Department, List<Employee>> byDept = employees.stream()
                    .collect(Collectors.groupingBy(Employee::getDepartment));

जहाँ विभाग आपकी कुंजी है


-9

LinkedHashMap की कोशिश करें , नमूना:

Map<String,String> map = new LinkedHashMap<String,String>();    
map.put('1','linked');map.put('1','hash');    
map.put('2','map');map.put('3','java');.. 

उत्पादन:

कुंजी: 1,1,2,3

मान: जुड़ा हुआ, हैश, मैप, जावा


7
यह काम नहीं करेगा। linkedअब नक्शे में मौजूद नहीं होगा क्योंकि आपने इसे बदल दिया है hash
जेफ मर्काडो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.