多图番石榴值
Multimap guava values
我有这种情况:
ID={1,2,3}
Title ={T1,T2,T3}
Place ={P1,P2,P3}
我想要这样的结果:
ID: 1 , Title: T1, Place: P1
ID: 2 , Title: T2, Place: P2
ID: 3 , Title: T3, Place: P3
我使用 Multimap (Guava) 来存储 ID 和标题及其多个值:
Multimap<String, String> MultiMap = ArrayListMultimap.create();
但是,到目前为止,我无法获得如上所述的预期结果。我尝试使用此代码:
for (Entry<String, String> key : MultiMap.entries())
{
System.out.println("name : " + key.getKey() + " value : " + key.getValue());
}
然而,使用这段代码我得到的结果是这样的:
name : ID value: 1
name : ID value: 2
name : ID value: 3
name : Title value: T1
name : Title value: T2
name : Title value: T3
name : Place value: P1
name : Place value: P2
name : Place value: P3
如何使用Multimap得到我上面描述的结果?
我认为您没有正确理解什么是 Multimap。 Multimap 从一个或多个键映射到多个值,它是一种 n-to-m 关系。您似乎拥有的是从 ID 到标题的关系,这是 n-to-1 关系。正确的数据结构是 Map,而不是 Multimap。
Map<Integer, String> titlesById = new TreeMap<>(); // keep map ordered by ID
titlesById.put(1, "T1");
titlesById.put(2, "T2");
titlesById.put(3, "T3");
for(Map.Entry<Integer, String> entry : titlesById.entrySet()){
System.out.println("ID : " + entry.getKey() + " Title : " + entry.getValue());
}
这应该会产生所需的输出。
注意:如果您可能从地图中按 ID 查找标题,那么您可能希望从 TreeMap 切换到 HashMap,因为 HashMap 具有恒定的时间查找。
更新:显然您确实需要一个 Multimap。然后把上面的代码改成这样:
Multimap<Integer, String> titlesById = TreeMultimap.create<>(); // keep map ordered by ID
titlesById.putAll(1, Arrays.asList("T1a", "T1b", "T1c"));
titlesById.putAll(2, Arrays.asList("T2a", "T2b"));
titlesById.put(3, "T3");
for(Map.Entry<Integer, String> entry : titlesById.entries()){
System.out.println("ID : " + entry.getKey() + " Title : " + entry.getValue());
}
再次:TreeMultimap
按键对 Map 进行排序,HashMultimap
具有高效的查找。
它变得越来越有趣,现在你想要将 3 个值相互连接起来。在这种情况下,您应该使用 Table
(3 维地图)。例如
Table<Integer, String, String> titlesAndPlacesById = TreeBasedTable.create();
titlesAndPlacesById.put(1, "T1", "P1");
titlesAndPlacesById.put(2, "T2", "P2");
titlesAndPlacesById.put(3, "T3", "P3");
for(Table.Cell<Integer, String, String> cell : titlesAndPlacesById.cellSet()){
System.out.println("ID : " + cell.getColumnKey() + " Title : " + cell.getRowKey() + ", Place: " + cell.getValue());
}
但这不是完美的匹配。如果你想将一个 ID 映射到一个标题和地点,那么你可能想要一个自定义 object 封装标题和地点,并将其用作从整数到自定义类型的普通旧 Map 中的值。
public class TitleAndPlace{
private final String title;
private final String place;
TitleAndPlace(String title, String place) {
this.title = title;
this.place = place;
}
public String getTitle() { return title; }
public String getPlace() { return place; }
@Override public boolean equals(Object o) {
if (this == o) return true;
else if (o instanceof TitleAndPlace) {
TitleAndPlace that = (TitleAndPlace) o;
return Objects.equals(title, that.title)
&& Objects.equals(place, that.place);
} else return false;
}
@Override public int hashCode() {
return Objects.hash(title, place);
}
}
Map<Integer, TitleAndPlace> map = new TreeMap<>();
map.put(1, new TitleAndPlace("T1", "P1"));
map.put(2, new TitleAndPlace("T2", "P2"));
for(Map.Entry<Integer, TitleAndPlace> entry : map.entrySet()){
System.out.println("ID : " + entry.getKey() + " Title : " + entry.getValue().getTitle() + ", Place: " + entry.getValue().getPlace());
}
我有这种情况:
ID={1,2,3}
Title ={T1,T2,T3}
Place ={P1,P2,P3}
我想要这样的结果:
ID: 1 , Title: T1, Place: P1
ID: 2 , Title: T2, Place: P2
ID: 3 , Title: T3, Place: P3
我使用 Multimap (Guava) 来存储 ID 和标题及其多个值:
Multimap<String, String> MultiMap = ArrayListMultimap.create();
但是,到目前为止,我无法获得如上所述的预期结果。我尝试使用此代码:
for (Entry<String, String> key : MultiMap.entries())
{
System.out.println("name : " + key.getKey() + " value : " + key.getValue());
}
然而,使用这段代码我得到的结果是这样的:
name : ID value: 1
name : ID value: 2
name : ID value: 3
name : Title value: T1
name : Title value: T2
name : Title value: T3
name : Place value: P1
name : Place value: P2
name : Place value: P3
如何使用Multimap得到我上面描述的结果?
我认为您没有正确理解什么是 Multimap。 Multimap 从一个或多个键映射到多个值,它是一种 n-to-m 关系。您似乎拥有的是从 ID 到标题的关系,这是 n-to-1 关系。正确的数据结构是 Map,而不是 Multimap。
Map<Integer, String> titlesById = new TreeMap<>(); // keep map ordered by ID
titlesById.put(1, "T1");
titlesById.put(2, "T2");
titlesById.put(3, "T3");
for(Map.Entry<Integer, String> entry : titlesById.entrySet()){
System.out.println("ID : " + entry.getKey() + " Title : " + entry.getValue());
}
这应该会产生所需的输出。
注意:如果您可能从地图中按 ID 查找标题,那么您可能希望从 TreeMap 切换到 HashMap,因为 HashMap 具有恒定的时间查找。
更新:显然您确实需要一个 Multimap。然后把上面的代码改成这样:
Multimap<Integer, String> titlesById = TreeMultimap.create<>(); // keep map ordered by ID
titlesById.putAll(1, Arrays.asList("T1a", "T1b", "T1c"));
titlesById.putAll(2, Arrays.asList("T2a", "T2b"));
titlesById.put(3, "T3");
for(Map.Entry<Integer, String> entry : titlesById.entries()){
System.out.println("ID : " + entry.getKey() + " Title : " + entry.getValue());
}
再次:TreeMultimap
按键对 Map 进行排序,HashMultimap
具有高效的查找。
它变得越来越有趣,现在你想要将 3 个值相互连接起来。在这种情况下,您应该使用 Table
(3 维地图)。例如
Table<Integer, String, String> titlesAndPlacesById = TreeBasedTable.create();
titlesAndPlacesById.put(1, "T1", "P1");
titlesAndPlacesById.put(2, "T2", "P2");
titlesAndPlacesById.put(3, "T3", "P3");
for(Table.Cell<Integer, String, String> cell : titlesAndPlacesById.cellSet()){
System.out.println("ID : " + cell.getColumnKey() + " Title : " + cell.getRowKey() + ", Place: " + cell.getValue());
}
但这不是完美的匹配。如果你想将一个 ID 映射到一个标题和地点,那么你可能想要一个自定义 object 封装标题和地点,并将其用作从整数到自定义类型的普通旧 Map 中的值。
public class TitleAndPlace{
private final String title;
private final String place;
TitleAndPlace(String title, String place) {
this.title = title;
this.place = place;
}
public String getTitle() { return title; }
public String getPlace() { return place; }
@Override public boolean equals(Object o) {
if (this == o) return true;
else if (o instanceof TitleAndPlace) {
TitleAndPlace that = (TitleAndPlace) o;
return Objects.equals(title, that.title)
&& Objects.equals(place, that.place);
} else return false;
}
@Override public int hashCode() {
return Objects.hash(title, place);
}
}
Map<Integer, TitleAndPlace> map = new TreeMap<>();
map.put(1, new TitleAndPlace("T1", "P1"));
map.put(2, new TitleAndPlace("T2", "P2"));
for(Map.Entry<Integer, TitleAndPlace> entry : map.entrySet()){
System.out.println("ID : " + entry.getKey() + " Title : " + entry.getValue().getTitle() + ", Place: " + entry.getValue().getPlace());
}