Chúng tôi có thể triển khai HashMap với một khóa và hai giá trị không. Cũng như HashMap?
Xin hãy giúp tôi, bằng cách nói (nếu không có cách nào) để thực hiện việc lưu trữ ba giá trị với một làm khóa?
Chúng tôi có thể triển khai HashMap với một khóa và hai giá trị không. Cũng như HashMap?
Xin hãy giúp tôi, bằng cách nói (nếu không có cách nào) để thực hiện việc lưu trữ ba giá trị với một làm khóa?
Câu trả lời:
Bạn có thể:
Map<KeyType, List<ValueType>>.Map<KeyType, WrapperType>.Map<KeyType, Tuple<Value1Type, Value2Type>>.1. Bản đồ với danh sách là giá trị
// 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];
Nhược điểm với phương pháp này là danh sách không bị ràng buộc với chính xác hai giá trị.
2. Sử dụng lớp bao bọc
// 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;
Nhược điểm của phương pháp này là bạn phải viết rất nhiều mã nồi hơi cho tất cả các lớp container rất đơn giản này.
3. Sử dụng bộ dữ liệu
// 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;
Đây là giải pháp tốt nhất theo ý kiến của tôi.
4. Nhiều bản đồ
// 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"];
Nhược điểm của giải pháp này là không rõ ràng rằng hai bản đồ có liên quan với nhau, một lỗi lập trình có thể thấy hai bản đồ không đồng bộ.
Map<KeyType, Tuple<Value1Type, Value2Type>>
Không, không chỉ là a HashMap. Về cơ bản, bạn cần HashMapmột khóa từ một khóa đến một tập hợp các giá trị.
Nếu bạn hài lòng khi sử dụng các thư viện bên ngoài, Guava có chính xác khái niệm này Multimapvới các triển khai như ArrayListMultimapvà HashMultimap.
ArrayListMultimapmình ... hoặc chỉ sử dụng một HashMap<String, List<Integer>>hoặc bất cứ điều gì. Về cơ bản, bạn cần tạo một danh sách trống bất cứ khi nào một giá trị được thêm vào.
HashMap<String, List<Integer>>
Một lựa chọn thú vị khác là sử dụng MultiValuedMap từ Apache Commons. Hãy xem tất cả các lớp triển khai đã biết ở đầu trang để triển khai chuyên ngành.
Thí dụ:
HashMap<K, ArrayList<String>> map = new HashMap<K, ArrayList<String>>()
có thể được thay thế bằng
MultiValuedMap<K, String> map = new MultiValuedHashMap<K, String>();
Vì thế,
map.put(key, "A");
map.put(key, "B");
map.put(key, "C");
Collection<String> coll = map.get(key);
sẽ dẫn đến bộ sưu tập collchứa "A", "B" và "C".
Hãy xem Multimaptừ các thư viện ổi và việc thực hiện nó -HashMultimap
Một bộ sưu tập tương tự như Bản đồ, nhưng có thể liên kết nhiều giá trị với một khóa duy nhất. Nếu bạn gọi put (K, V) hai lần, với cùng một khóa nhưng các giá trị khác nhau, multimap chứa ánh xạ từ khóa tới cả hai giá trị.
Tôi sử dụng Map<KeyType, Object[]>để liên kết nhiều giá trị với một khóa trong Bản đồ. Bằng cách này, tôi có thể lưu trữ nhiều giá trị thuộc các loại khác nhau được liên kết với một khóa. Bạn phải cẩn thận bằng cách duy trì thứ tự chèn và truy xuất thích hợp từ Object [].
Ví dụ: Xem xét, chúng tôi muốn lưu trữ thông tin sinh viên. Key là id, trong khi chúng tôi muốn lưu trữ tên, địa chỉ và email liên quan đến sinh viên.
//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];
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);
Chỉ cần cho bản ghi, giải pháp JDK8 thuần túy sẽ sử dụng Map::computephương thức:
map.compute(key, (s, strings) -> strings == null ? new ArrayList<>() : strings).add(value);
Nhu la
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);
}
với đầu ra:
bar: foo
first: hello, foo, hello
Lưu ý rằng để đảm bảo tính nhất quán trong trường hợp nhiều luồng truy cập cấu trúc dữ liệu này ConcurrentHashMapvà CopyOnWriteArrayListví dụ cần phải được sử dụng.
computeIfAbsent. map.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
Nếu bạn sử dụng Spring Framework . Có : org.springframework.util.MultiValueMap.
Để tạo bản đồ đa giá trị không thể thay đổi:
Map<String,List<String>> map = ...
MultiValueMap<String, String> multiValueMap = CollectionUtils.toMultiValueMap(map);
Hoặc dùng org.springframework.util.LinkedMultiValueMap
Vâng, điều này thường được gọi là a multimap.
Cách dễ nhất là sử dụng thư viện bộ sưu tập 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
}
}
liên kết maven: https://mvnreposective.com/artifact/com.google.collections/google-collections/1.0-rc2
thêm về điều này: http://tomjefferys.blogspot.be/2011/09/multimaps-google-guava.html
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);
}
Tôi đã có kết quả tốt nhất.
Bạn chỉ cần tạo HashMaplike mới
HashMap<String, String> servicesNameHashmap = new HashMap<String, String>();
trong forvòng lặp của bạn . Nó sẽ có cùng hiệu ứng như cùng khóa và nhiều giá trị.
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"));
}
}
Đầu ra:
{"1"=["11","12","13","14"],"11"=["111"],"12"=["121"]}
["111"]
Đây là thư viện Google-Guava cho các chức năng tiện ích. Đây là giải pháp cần thiết.
Tôi không thể đăng bài trả lời về bình luận của Paul vì vậy tôi đang tạo bình luận mới cho Vidhya tại đây:
Wrapper sẽ là một giá SuperClasstrị cho hai lớp mà chúng ta muốn lưu trữ dưới dạng giá trị.
và bên trong lớp trình bao bọc, chúng ta có thể đặt các liên kết làm đối tượng biến đối tượng cho hai đối tượng lớp.
ví dụ
class MyWrapper {
Class1 class1obj = new Class1();
Class2 class2obj = new Class2();
...
}
và trong HashMap, chúng ta có thể đặt theo cách này,
Map<KeyObject, WrapperObject>
WrapperObj sẽ có các biến lớp:class1Obj, class2Obj
Bạn có thể làm điều đó ngầm.
// 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";
Điều này rất đơn giản và hiệu quả. Nếu bạn muốn các giá trị của các lớp khác nhau thay vào đó, bạn có thể làm như sau:
HashMap<Integer, Object[]> map = new HashMap<Integer, Object[]>();
Có thể được thực hiện bằng cách sử dụng một danh tínhHashMap, với điều kiện là việc so sánh các khóa sẽ được thực hiện bởi toán tử == và không bằng ().
Tôi đã quá quen với việc chỉ làm điều này với Từ điển dữ liệu trong Mục tiêu C. Khó có được kết quả tương tự trong Java cho Android. Tôi đã kết thúc việc tạo một lớp tùy chỉnh, và sau đó chỉ thực hiện một hashmap của lớp tùy chỉnh của tôi.
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;
}
}
Chúng ta có thể tạo một lớp để có nhiều khóa hoặc giá trị và đối tượng của lớp này có thể được sử dụng làm tham số trong bản đồ. Bạn có thể tham khảo https://stackoverflow.com/a/44181931/8065321
Sử dụng các bộ sưu tập Java
// Group employees by department
Map<Department, List<Employee>> byDept = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
Sở là chìa khóa của bạn ở đâu
Hãy thử LinkedHashMap , mẫu:
Map<String,String> map = new LinkedHashMap<String,String>();
map.put('1','linked');map.put('1','hash');
map.put('2','map');map.put('3','java');..
đầu ra:
các phím: 1,1,2,3
các giá trị: được liên kết, hàm băm, bản đồ, java
linkedsẽ không tồn tại trong bản đồ nữa vì bạn đã thay thế nó bằng hash.