একই কী এর অধীনে একাধিক মান সহ হ্যাশম্যাপ


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;

এটি আমার মতে সেরা সমাধান।

৪. একাধিক মানচিত্র

// 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

@ পল, # 3 এর জন্য যে কোনও সাধারণ উদাহরণ কোড Map<KeyType, Tuple<Value1Type, Value2Type>>
জোয়ার্ডার কামাল

@ কুলমাইন্ড আমি নিশ্চিত মানুষ ভুলত্রুটিগুলি সমাধান করতে পারে: অথবা আপনি এগুলি সম্ভবত সংশোধন করতে পারেন?
পল রুনে

61

না, শুধু হিসাবে না HashMap। আপনার মূলত HashMapএকটি কী থেকে শুরু করে মান সংগ্রহের প্রয়োজন।

আপনি বহিরাগত লাইব্রেরি ব্যবহার করতে খুশি থাকেন, পেয়ারা ঠিক এই ধারণা হয়েছে Multimapযেমন বাস্তবায়নের সঙ্গে ArrayListMultimapএবং HashMultimap


@ জোন, আপনি ওপি কর্তৃক জিজ্ঞাসিত উপরের প্রশ্নের জন্য জাভাতে উইথ ওয়ার্কিং উদাহরণ প্রদান করতে পারেন। আপনি যদি এটি পোস্ট করতে পারেন তবে খুব প্রশংসা করেছেন
দীপক

2
@ প্রদীপ: পেয়ারা মাল্টিম্যাপের উদাহরণ অনুসন্ধান করুন এবং আপনি নমুনা কোডটি পাবেন।
জন স্কিটি

1
@ প্রদীপ: মূলত আপনি ArrayListMultimapনিজের মতো কিছু তৈরি করতে চাইতেন ... বা কেবল কিছু HashMap<String, List<Integer>>বা যা ব্যবহার করুন । মূলত প্রথমবারের জন্য কোনও মান যুক্ত হওয়ার পরে আপনাকে একটি খালি তালিকা তৈরি করতে হবে।
জন স্কিটি

1
আপনার কি কার্যকরী উদাহরণ রয়েছেHashMap<String, List<Integer>>
দীপক

9
@ প্রদীপ: আমি আপনাকে পরামর্শ দিচ্ছি যে আপনি নিজেই একটি উদাহরণ তৈরি করার চেষ্টা করুন এবং যদি আপনি আটকে যান তবে কোড সহ একটি প্রশ্ন জিজ্ঞাসা করুন যতদূর আপনি পেয়েছেন। আপনি সেভাবে আরও অনেক কিছু শিখবেন।
জন স্কিটি

23

আরেকটি দুর্দান্ত পছন্দ হ'ল অ্যাপাচি কমন্স থেকে মাল্টিভ্যালুডম্যাপ ব্যবহার করা । কটাক্ষপাত সমস্ত জানা বাস্তবায়নকারী ক্লাস বিশেষ বাস্তবায়নের জন্য পৃষ্ঠার উপরের।

উদাহরণ:

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"এ", "বি" এবং "সি" সমন্বিত ফলাফলের ফলাফল হবে ।


13

কটাক্ষপাত Multimapপেয়ারা-লাইব্রেরি ও তার বাস্তবায়ন থেকে -HashMultimap

মানচিত্রের অনুরূপ সংগ্রহ, তবে এটি একক কীতে একাধিক মানকে সংযুক্ত করতে পারে। যদি আপনি একই (কী, ভি) দু'বার একই কী কিন্তু বিভিন্ন মান সহ কল ​​করেন তবে মাল্টিম্যাপে কী থেকে উভয় মানের ম্যাপিং রয়েছে।


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);
saka1029

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

সবচেয়ে সহজ উপায় হ'ল গুগল সংগ্রহ লাইব্রেরি ব্যবহার করা:

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"]

এটি ইউটিলিটি কার্যকারিতার জন্য গুগল-পেয়ারা গ্রন্থাগার। এটি প্রয়োজনীয় সমাধান।


এটি একটি বৈধ সমাধান এবং আমি বেশ কয়েকবার এই পদ্ধতির ব্যবহার করেছি।
লেটোয়ানকা

হ্যাঁ এটি কাজ করছে তবে এটি ফর্মেটে ডেটা দেখিয়ে দিচ্ছে আমি একের পর এক আইটেমগুলি চাই যে কীভাবে এখানে আটকে যায়
সুনীল চৌধুরী চৌধুরী

0

আমি পলের মন্তব্যে কোনও উত্তর পোস্ট করতে পারিনি তাই আমি এখানে বিদ্যা সম্পর্কে নতুন মন্তব্য তৈরি করছি:

মোড়ক SuperClassদুটি শ্রেণীর জন্য একটি হবে যা আমরা মান হিসাবে সঞ্চয় করতে চাই।

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

যেমন

class MyWrapper {

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

এবং হ্যাশম্যাপে আমরা এইভাবে রাখতে পারি,

Map<KeyObject, WrapperObject> 

র্যাপারঅবজে ক্লাস ভেরিয়েবল থাকবে: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
জেফ মার্কাডো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.