[英]How to copy values from HashMap into an ArrayList using a Pair object class
So I am trying to figure out how to move my Pair<Key, Value> from the HashMap that they are originally in, into an ArrayList.所以我想弄清楚如何将我的 Pair<Key, Value> 从它们最初所在的 HashMap 移动到 ArrayList 中。 Nothing I am doing seems to be working and I am at a loss for how to copy the Keys & Values over.我所做的一切似乎都不起作用,我不知道如何复制键和值。
The Pair class: class 对:
public class Pair<K,V> {
private K key;
private V value;
public Pair(K key, V value)
{ this.key = key; this.value = value; }
public K getKey() { return key; }
public V getValue() { return value; }
}
And here is the ArrayList that I am attempting to put them into: ArrayList<Pair<String,Integer>> wcList = new ArrayList<>();
这是我试图将它们放入的 ArrayList: ArrayList<Pair<String,Integer>> wcList = new ArrayList<>();
For the above ArrayList I am given a HashMap<String, Integer> as a parameter.对于上面的 ArrayList,我得到了一个 HashMap<String, Integer> 作为参数。 The return must be an ArrayList<Pair<String, Integer>>返回必须是 ArrayList<Pair<String, Integer>>
** Using an entrySet does not work for my test cases ** ** 使用 entrySet 不适用于我的测试用例 **
This is a one-liner.这是一个单行。 Stream out the map's entry set, and convert each entry to a Pair
. Stream 取出地图的条目集,并将每个条目转换为Pair
。 Then collect them into a list.然后将它们收集到一个列表中。
yourMap.entrySet().stream().map(e->new Pair(e.getKey(), e.getValue())).collect(Collectors.toList());
The existing Map.Entry
interface does the job of your Pair
class, including getKey
& getValue
methods.现有的Map.Entry
接口可以完成Pair
class 的工作,包括getKey
和getValue
方法。 In your case, use Map.Entry < String, Integer >
.在您的情况下,请使用Map.Entry < String, Integer >
。
Example: From a Map
of student name (key) to their grade (value), produce a List
of the key-value pairings, sorted first by their grade (highest first), then by their name alphabetically.示例:从学生姓名(键)到他们的年级(值)的Map
生成一个键值对List
,首先按他们的年级(最高的在前)排序,然后按他们的姓名字母顺序排序。
var entriesSorted =
new TreeSet <>(
Comparator
.comparing( Map.Entry < String, Integer > :: getValue ).reversed() // Reversed for highest grades first.
.thenComparing( Map.Entry < String, Integer > :: getKey ) // Names sort alphabetically.
);
entriesSorted.addAll(
Map
.of(
"Alice" , 4 , // Student, Grade
"Bobby" , 2 ,
"Carol" , 3 ,
"Davis" , 4 ,
"Edith" , 1 ,
"Frank" , 3
)
.entrySet()
);
var list = List.copyOf( entriesSorted );
list.toString() = [Alice=4, Davis=4, Carol=3, Frank=3, Bobby=2, Edith=1] list.toString() = [爱丽丝=4,戴维斯=4,卡罗尔=3,弗兰克=3,鲍比=2,伊迪丝=1]
Or, if you insist upon your Pair
class, use Stream#map
to transfer the key & value from each Map.Entry
to a new Pair
object.或者,如果您坚持使用您的Pair
class,请使用Stream#map
将密钥和值从每个Map.Entry
到新的Pair
object。
List < Pair > list =
Map
.of(
"Alice" , 4 , // Student, Grade
"Bobby" , 2 ,
"Carol" , 3 ,
"Davis" , 4 ,
"Edith" , 1 ,
"Frank" , 3
)
.entrySet() // Returns a `Set` of `Map.Entry` objects.
.stream()
.map( entry -> new Pair( entry.getKey() , entry.getValue() ) )
.toList();
list = [Pair{key=Edith, value=1}, Pair{key=Alice, value=4}, Pair{key=Carol, value=3}, Pair{key=Frank, value=3}, Pair{key=Bobby, value=2}, Pair{key=Davis, value=4}] list = [Pair{key=Edith, value=1}, Pair{key=Alice, value=4}, Pair{key=Carol, value=3}, Pair{key=Frank, value=3}, Pair{key =鲍比,价值=2},对{键=戴维斯,价值=4}]
Map.Entry
instead of your Pair
Map.Entry
而不是你的Pair
A Map
already provides what you want. Map
已经提供了您想要的。
You imply that you already have a Map < String, Integer >
, using HashMap
as your implementation.您暗示您已经有一个Map < String, Integer >
,使用HashMap
作为您的实现。
You want a List
of the key-value pairs contained in that Map.您需要包含在 Map 中的键值对List
。 To represent those key-value pairs, you created a Pair
class.为了表示这些键值对,您创建了一个Pair
class。 But there is no need for your Pair
class .但是不需要您的Pair
class 。 The Map.Entry
interface already provides the key-value pairing object you desire. Map.Entry
接口已经提供了您想要的键值对 object。 To quote the Javadoc:引用 Javadoc:
Map.Entry<K,V>
… A map entry (key-value pair).Map.Entry<K,V>
... map 条目(键值对)。
A Map.Entry
object offers getKey
and getValue
methods, to access their contents. A Map.Entry
object 提供getKey
和getValue
方法,以访问它们的内容。
You can easily produce a Set
of those Entry
objects, with a built-in method on every Map
.您可以使用每个Map
上的内置方法轻松生成一Set
这些Entry
对象。
Map< String , Integer > myMap = new HashMap<>() ;
…
Set< String , Integer > pairs = myMap.entrySet() ;
A Set
is appropriate here, because your HashMap
by definition has no promised order. Set
在这里是合适的,因为根据定义,您的HashMap
没有承诺的订单。 So a List
, which keeps elements in a sequence, makes no sense.因此,将元素保持在序列中的List
没有任何意义。
Here is some example code, using student name mapped to their class grade.这是一些示例代码,使用映射到 class 成绩的学生姓名。
Instead of a HashMap
, I use an unspecified Map
implementation produced by the convenient Map.of
method.代替HashMap
,我使用由方便的Map.of
方法生成的未指定Map
实现。
Map < String, Integer > studentGrades =
Map.of(
"Alice" , 4 ,
"Bob" , 2 ,
"Carol" , 3 ,
"Davis" , 4 ,
"Edith" , 1 ,
"Frank" , 3
);
Set < Map.Entry < String, Integer > > entries = studentGrades.entrySet();
entries.forEach( System.out :: println ); // Call `toString` on each `Entry` object.
When run:运行时:
Davis=4
Edith=1
Alice=4
Bob=2
Carol=3
Frank=3
You needn't work out that exact type of Set < Map.Entry < String, Integer > > entries
;你不需要计算出Set < Map.Entry < String, Integer > > entries
的确切类型; just use var
to let the compiler figure it out.只需使用var
让编译器弄清楚。
var entries = studentGrades.entrySet();
var entries = studentGrades.entrySet();
If you want to keep those entries in a specific order, use a NavigableSet
(or SortedSet
) such as TreeSet
.如果您想按特定顺序保留这些条目,请使用NavigableSet
(或SortedSet
),例如TreeSet
。 You will need to provide the rule by which to order them.您需要提供订购它们的规则。
Let's say we want them sorted by the student's grades, highest grades first.假设我们希望它们按学生的成绩排序,首先是最高成绩。
NavigableSet < Map.Entry < String, Integer > > entriesByGrade =
new TreeSet <>(
Comparator
.comparing( Map.Entry < String, Integer > :: getValue ).reversed()
.thenComparing( Map.Entry < String, Integer > :: getKey )
);
entriesByGrade.addAll( entries );
entriesByGrade.toString() = [Alice=4, Davis=4, Carol=3, Frank=3, Bob=2, Edith=1] entryByGrade.toString() = [爱丽丝=4,戴维斯=4,卡罗尔=3,弗兰克=3,鲍勃=2,伊迪丝=1]
If you really need a List
, you can make one from the NavigableSet
.如果你真的需要一个List
,你可以从NavigableSet
中创建一个。
List < Map.Entry < String, Integer > > listOfStudentsByGrade = List.copyOf( entriesByGrade );
Or more simply, use var
.或者更简单地说,使用var
。
var listOfStudentsByGrade = List.copyOf( entriesByGrade );
Either way, when run:无论哪种方式,运行时:
listOfStudentsByGrade.toString() = [Alice=4, Davis=4, Carol=3, Frank=3, Bob=2, Edith=1] listOfStudentsByGrade.toString() = [爱丽丝=4,戴维斯=4,卡罗尔=3,弗兰克=3,鲍勃=2,伊迪丝=1]
Pair
class使用您的Pair
class As discussed in this Answer, and in the Comments, your Pair
class is utterly superfluous, with Map.Entry
already doing its job.正如本答案和评论中所讨论的,您的Pair
class 完全是多余的, Map.Entry
已经完成了它的工作。
But if you insist, you could easily pull the key & value out of each entry, then put that same key and value into an object of your Pair
class.但是,如果您坚持,您可以轻松地从每个条目中提取键和值,然后将相同的键和值放入您的Pair
class 的 object 中。 Silly, but easy.愚蠢,但很容易。
List < Pair > list =
Map
.of(
"Alice" , 4 , // Student, Grade
"Bobby" , 2 ,
"Carol" , 3 ,
"Davis" , 4 ,
"Edith" , 1 ,
"Frank" , 3
)
.entrySet()
.stream()
.map( entry -> new Pair( entry.getKey() , entry.getValue() ) )
.toList();
Here's a bit of code that populates a Map, and then prints out the map contents:这是填充 Map 的代码,然后打印出 map 内容:
Map<String, Integer> map = new HashMap<>();
map.put("aardvark", 1);
map.put("bear", 2);
map.put("cat", 3);
System.out.println("map: " + map);
map: {cat=3, aardvark=1, bear=2}
Using that map, here's a bit of code that:使用 map,这里有一些代码:
toString()
method to the Pair class (posted below) so that the list printing is more informative另外,我在 Pair class 中添加了一个toString()
方法(发布在下面),以便列表打印提供更多信息List<Pair<String, Integer>> list = new ArrayList<>();
for (String key : map.keySet()) {
Integer value = map.get(key);
Pair<String, Integer> pair = new Pair<>(key, value);
list.add(pair);
}
System.out.println("list: " + list);
list: [Pair{key=cat, value=3}, Pair{key=aardvark, value=1}, Pair{key=bear, value=2}]
Here's the addition to Pair so that the list contents can be printed nicely:这是对 Pair 的补充,以便可以很好地打印列表内容:
@Override
public String toString() {
return "Pair{" +
"key=" + key +
", value=" + value +
'}';
}
You could also solve it with streams:您也可以使用流解决它:
List<Pair<String, Integer>> list = map
.keySet()
.stream()
.map(key -> new Pair<>(key, map.get(key)))
.toList();
The below code seperates the keys and values from HashMap and creates 2 ArrayLists to hold them.下面的代码将键和值从 HashMap 中分离出来,并创建 2 个 ArrayList 来保存它们。
Please refer the extract method.请参考提取方法。
For the above ArrayList I am given a HashMap<String, Integer> as a parameter.对于上面的 ArrayList,我得到了一个 HashMap<String, Integer> 作为参数。 The return must be an ArrayList<Pair<String, Integer>>返回必须是 ArrayList<Pair<String, Integer>>
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("one", 1);
map.put("two", 2);
map.put("three", 3);
extract(map);
}
public static ArrayList<Pair<String, Integer>> extract(HashMap map)
{
ArrayList<Pair<String, Integer>> list = new ArrayList<Pair<String,Integer>>();
ArrayList<String> mapKeys = new ArrayList<String>(map.keySet());
ArrayList<Integer> mapValues = new ArrayList<Integer>(map.values());
Pair p;
for(int i=0; i<map.size(); i++) {
p = new Pair(mapKeys.get(i), mapValues.get(i));
list.add(p);
}
list.stream().forEach(e ->System.out.println(e.toString()));
return list;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.