[英]How to overwrite values of HashMap from ArrayList using Java 8 Streams
[英]How to copy values from HashMap into an ArrayList using a Pair object class
所以我想弄清楚如何将我的 Pair<Key, Value> 从它们最初所在的 HashMap 移动到 ArrayList 中。 我所做的一切似乎都不起作用,我不知道如何复制键和值。
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; }
}
这是我试图将它们放入的 ArrayList: ArrayList<Pair<String,Integer>> wcList = new ArrayList<>();
对于上面的 ArrayList,我得到了一个 HashMap<String, Integer> 作为参数。 返回必须是 ArrayList<Pair<String, Integer>>
** 使用 entrySet 不适用于我的测试用例 **
这是一个单行。 Stream 取出地图的条目集,并将每个条目转换为Pair
。 然后将它们收集到一个列表中。
yourMap.entrySet().stream().map(e->new Pair(e.getKey(), e.getValue())).collect(Collectors.toList());
现有的Map.Entry
接口可以完成Pair
class 的工作,包括getKey
和getValue
方法。 在您的情况下,请使用Map.Entry < String, Integer >
。
示例:从学生姓名(键)到他们的年级(值)的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() = [爱丽丝=4,戴维斯=4,卡罗尔=3,弗兰克=3,鲍比=2,伊迪丝=1]
或者,如果您坚持使用您的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 =鲍比,价值=2},对{键=戴维斯,价值=4}]
Map.Entry
而不是你的Pair
Map
已经提供了您想要的。
您暗示您已经有一个Map < String, Integer >
,使用HashMap
作为您的实现。
您需要包含在 Map 中的键值对List
。 为了表示这些键值对,您创建了一个Pair
class。 但是不需要您的Pair
class 。 Map.Entry
接口已经提供了您想要的键值对 object。 引用 Javadoc:
Map.Entry<K,V>
... map 条目(键值对)。
A Map.Entry
object 提供getKey
和getValue
方法,以访问它们的内容。
您可以使用每个Map
上的内置方法轻松生成一Set
这些Entry
对象。
Map< String , Integer > myMap = new HashMap<>() ;
…
Set< String , Integer > pairs = myMap.entrySet() ;
Set
在这里是合适的,因为根据定义,您的HashMap
没有承诺的订单。 因此,将元素保持在序列中的List
没有任何意义。
这是一些示例代码,使用映射到 class 成绩的学生姓名。
代替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.
运行时:
Davis=4
Edith=1
Alice=4
Bob=2
Carol=3
Frank=3
你不需要计算出Set < Map.Entry < String, Integer > > entries
的确切类型; 只需使用var
让编译器弄清楚。
var entries = studentGrades.entrySet();
var entries = studentGrades.entrySet();
如果您想按特定顺序保留这些条目,请使用NavigableSet
(或SortedSet
),例如TreeSet
。 您需要提供订购它们的规则。
假设我们希望它们按学生的成绩排序,首先是最高成绩。
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 );
entryByGrade.toString() = [爱丽丝=4,戴维斯=4,卡罗尔=3,弗兰克=3,鲍勃=2,伊迪丝=1]
如果你真的需要一个List
,你可以从NavigableSet
中创建一个。
List < Map.Entry < String, Integer > > listOfStudentsByGrade = List.copyOf( entriesByGrade );
或者更简单地说,使用var
。
var listOfStudentsByGrade = List.copyOf( entriesByGrade );
无论哪种方式,运行时:
listOfStudentsByGrade.toString() = [爱丽丝=4,戴维斯=4,卡罗尔=3,弗兰克=3,鲍勃=2,伊迪丝=1]
Pair
class 正如本答案和评论中所讨论的,您的Pair
class 完全是多余的, Map.Entry
已经完成了它的工作。
但是,如果您坚持,您可以轻松地从每个条目中提取键和值,然后将相同的键和值放入您的Pair
class 的 object 中。 愚蠢,但很容易。
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();
这是填充 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}
使用 map,这里有一些代码:
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}]
这是对 Pair 的补充,以便可以很好地打印列表内容:
@Override
public String toString() {
return "Pair{" +
"key=" + key +
", value=" + value +
'}';
}
您也可以使用流解决它:
List<Pair<String, Integer>> list = map
.keySet()
.stream()
.map(key -> new Pair<>(key, map.get(key)))
.toList();
下面的代码将键和值从 HashMap 中分离出来,并创建 2 个 ArrayList 来保存它们。
请参考提取方法。
对于上面的 ArrayList,我得到了一个 HashMap<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.