我们是否可以用一个键和两个值实现HashMap。就像HashMap吗?

请帮我一个忙,也告诉(如果没有办法)以其他方式实现以一个为键的三个值的存储吗?

评论

如何在地图中存储多个字符串的可能重复项?

谢谢朋友...但是我在使用MultiHashMap时有一些限制

具有重复键的Map实现的可能重复

#1 楼

您可以:


使用具有列表作为值的地图。 Map<KeyType, List<ValueType>>
创建一个新的包装器类,并将该包装器的实例放置在地图中。 Map<KeyType, WrapperType>
使用类似元组的类(节省创建许多包装器)。 Map<KeyType, Tuple<Value1Type, Value2Type>>
并排使用多个地图。


示例

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
2011-2-10 13:42

@vidhya:哪个特别适合您的问题?您的多个对象是相同类型还是不同?

– Paul Ruane
2011-2-10 14:49

榜样实际上会很棒。

– Xonatron
2012-2-10 21:08

@ Paul,#3 Map >的任何简单示例代码

–乔德·卡马尔(Joarder Kamal)
13年6月24日在13:39

@CoolMind我确定人们可以解决这些错误:或者您可以纠正它们?

– Paul Ruane
15年12月24日在16:16

#2 楼

不,不仅仅是HashMap。从键到值的集合基本上就需要一个HashMap。 br />

评论


@Jon,您能为OP提出的上述问题提供Java的工作示例吗,非常感谢您可以发布

– Deepak
2011-02-10 18:04

@Deepak:搜索番石榴多图示例,您将找到示例代码。

–乔恩·斯基特(Jon Skeet)
2011-02-10 18:11

@Deepak:基本上,您可以自己构建类似ArrayListMultimap的东西……或只使用HashMap >或其他任何东西。基本上,每次添加值时,您都需要创建一个空列表。

–乔恩·斯基特(Jon Skeet)
2011-02-10 18:20

你有一个HashMap >的工作示例吗

– Deepak
2011-02-10 18:26

@Deepak:我建议您尝试自己创建一个示例,如果遇到困难,请提出一个问题,包括您所拥有的代码。这样您将学到更多。

–乔恩·斯基特(Jon Skeet)
2011-2-10在19:28

#3 楼

另一个不错的选择是使用来自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”。

#4 楼

从guava库中查看Multimap及其实现-HashMultimap


一个类似于Map的集合,但是可以将多个值与单个键关联。如果使用相同的键但值不同的方法两次调用put(K,V),则多重映射将包含从键到两个值的映射。


#5 楼

我使用Map<KeyType, Object[]>将多个值与Map中的键相关联。这样,我可以存储与键关联的不同类型的多个值。您必须通过保持正确的从Object []插入和检索的顺序来保重。

示例:
考虑一下,我们要存储学生信息。密钥是ID,而我们希望存储与该学生相关的姓名,地址和电子邮件。

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


评论


对我来说,这是最好的答案。它更简单,更简洁,更抽象。

–莫雷
17年1月4日,下午3:25

#6 楼

HashMap<Integer,ArrayList<String>> map = new    HashMap<Integer,ArrayList<String>>();

ArrayList<String> list = new ArrayList<String>();
list.add("abc");
list.add("xyz");
map.put(100,list);


#7 楼

仅作记录,纯JDK8解决方案将使用Map::compute方法: />输出:

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


请注意,为确保多个线程访问此数据结构时的一致性,需要使用ConcurrentHashMapCopyOnWriteArrayList

评论


最好使用computeIfAbsent。 map.computeIfAbsent(key,k-> new ArrayList <>())。add(value);

–saka1029
16 Dec 30'0:54

#8 楼

如果使用Spring Framework。有:org.springframework.util.MultiValueMap

要创建不可修改的多值映射:

#9 楼

最简单的方法是使用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
    }

}


Maven链接:https://mvnrepository.com/artifact/com.google.collections/google- collections / 1.0-rc2

有关此的更多信息:http://tomjefferys.blogspot.be/2011/09/multimaps-google-guava.html

#10 楼

是的,没有。解决方案是为您的值构建一个Wrapper类,其中包含与您的键相对应的2个(3个或更多)值。

#11 楼

是的,通常被称为multimap

请参阅:http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/collect/Multimap .html

#12 楼

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循环。它将具有与相同的键和多个值相同的效果。

#13 楼

 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库。这是必需的解决方案。

评论


这是一个有效的解决方案,我已经多次使用这种方法。

–letowianka
5月12日16:08

是的,它可以正常工作,但是它正在[]格式中显示数据,我希望这些项目一个接一个地显示如何将其卡在此处

– Sunil Chaudhary
5月13日7:10

#14 楼

我无法对Paul的评论发表评论,所以我在这里为Vidhya创建新评论:

对于我们要存储为值的两个类,包装器将是SuperClass。 br />和在包装类中,我们可以将关联作为两个类对象的实例变量对象。

例如

class MyWrapper {

 Class1 class1obj = new Class1();
 Class2 class2obj = new Class2();
...
}
在HashMap中,我们可以这样写:

Map<KeyObject, WrapperObject> 


WrapperObj将具有类变量:class1Obj, class2Obj

#15 楼

您可以隐式地进行操作。

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


这非常简单且有效。
如果要使用不同类的值,则可以执行以下操作: br />
HashMap<Integer, Object[]> map = new HashMap<Integer, Object[]>();


#16 楼

可以使用identityHashMap来完成,但条件是键比较将由==运算符而不是equals()完成。

#17 楼

我更喜欢以下内容来存储任意数量的变量,而不必创建单独的类。

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


#18 楼

我习惯在Objective C中使用数据字典来执行此操作。在Java for Android中很难获得类似的结果。我最终创建了一个自定义类,然后只是对我的自定义类进行哈希映射。

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;
    }

}


#19 楼

我们可以创建一个具有多个键或值的类,并且该类的对象可用作map中的参数。
您可以参考https://stackoverflow.com/a/44181931/8065321

#20 楼

使用Java收集器

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


其中部门是您的关键

#21 楼

Apache Commons集合类可以在同一键下实现多个值。
    MultiMap multiMapDemo = new MultiValueMap();

    multiMapDemo .put("fruit", "Mango");
    multiMapDemo .put("fruit", "Orange");
    multiMapDemo.put("fruit", "Blueberry");

    System.out.println(multiMap.get("fruit"));

Maven依赖项
    <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -- 
     >
     <dependency>
         <groupId>org.apache.commons</groupId>
         <artifactId>commons-collections4</artifactId>
         <version>4.4</version>
    </dependency>


#22 楼

尝试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
值:链接,哈希,地图,java

评论


那行不通。链接将不再存在于地图中,因为您已将其替换为哈希。

–杰夫·梅卡多(Jeff Mercado)
13年4月19日在18:44