添加到列表后清除 HashMap,在 Java
Clear a HashMap after adding to a List, in Java
如果您能帮助我完成以下 Java 代码,我将不胜感激:
import java.util.ArrayList;
import java.util.HashMap;
public class JavaApplication2 {
static ArrayList<HashMap> list_test = new ArrayList<HashMap>();
static HashMap<String,String> test =new HashMap<>();
public static void main(String[] args) {
test.put("name", "jhon");
test.put("lastname", "mckoy");
list_test.add(test);
test.clear();
System.out.println(list_test);
test.put("name", "Tom");
test.put("lastname", "Red");
list_test.add(test);
}
}
我有两个变量,一个叫 list_test (ArrayList),另一个叫 test (HashMap )。我的目标是用下面的代码做一个HashMap的ArrayList,但是执行后:test.clear ();
然后list_test的内容被删除了。为什么?
还有另一种方法来制作 HashMap 列表吗?哪个?
提前致谢
tl;博士
使用您的代码,您放入列表中的同一地图对象就是您清除的同一地图对象。相反,将地图 的 copy 添加到列表中。
listOfMapsOfNames.add( Map.copyOf( mapOfNames ) ); // Make an unmodifiable copy of map to be added to list.
复制您的地图
显然您想要将地图的副本 添加到列表中。
您的代码将原始地图放入列表中。所以现在您有两个对同一个地图的引用:(a) 变量 test
指向地图,并且 (b) 列表中名为 list_test
的第一个元素指向同一个地图对象。如果您使用任何一个引用来更改地图的内容,那么两个引用都会看到该更改,因为它们都指向同一个对象。
或者:
- 调用
Map.copyOf
to make an unmodifiable地图副本。例如:Map.copyOf( oldMap )
- 将映射传递给另一个
Map
实现的构造函数,以将条目复制到新的可修改映射中。例如:new HashMap<>( oldMap )
.
您应该考虑养成在参考文献中使用更通用的超级 class 或接口而不是具体的 class 的习惯。所以 List<Map> list_test
而不是 ArrayList<HashMap> list_test
.
您应该参数化 List
的参数化。所以 List< Map< String, String > >
而不是 List< Map >
.
在您的 Java 标识符上使用更具描述性的名称将使您的代码更易于阅读和调试。所以像 listOfMapsOfNames
而不是 list_test
.
示例代码
这是一些示例代码。
我在地图上删除了 static
并列出,因为它无关紧要。
注意这两个调用 Map.copyOf( mapOfNames )
。
List< Map< String, String > > listOfMapsOfNames = new ArrayList<>() ;
Map< String, String > mapOfNames = new HashMap<>() ;
mapOfNames.put( "name", "John" );
mapOfNames.put( "lastname", "McKoy" );
listOfMapsOfNames.add( Map.copyOf( mapOfNames ) ); // Make an unmodifiable copy of map to be added to list.
System.out.println( "map before clear: " + mapOfNames );
mapOfNames.clear();
System.out.println( "map after clear: " + mapOfNames );
mapOfNames.put( "name", "Tom" );
mapOfNames.put( "lastname" , "Red" );
listOfMapsOfNames.add( Map.copyOf( mapOfNames ) ); // Make an unmodifiable copy of map to be added to list.
System.out.println( "map after 2nd add: " + mapOfNames );
System.out.println( "list at the end: " + listOfMapsOfNames );
看到这个 code run live at IdeOne.com。
map before clear: {name=John, lastname=McKoy}
map after clear: {}
map after 2nd add: {name=Tom, lastname=Red}
list at the end: [{lastname=McKoy, name=John}, {lastname=Red, name=Tom}]
record
与您的问题无关,但供您参考,使用 class 可能比使用 Map
跟踪名字和姓氏更有意义。现在我们有一种更简单的方法来编写这样的 class:records.
records feature is new in Java 16。记录是编写 class 的一种简短方式,其主要目的是透明且不可变地传递数据。编译器隐式创建构造函数、getter、equals
& hashCode
和 toString
。奖励:记录可以在本地声明,也可以嵌套或单独声明。
请注意,使用 record
.
,您的代码的以下版本变得更具表现力(并且更短)
record Person(String firstName , String lastName) {}
List < Person > people = new ArrayList <>();
people.add( new Person( "John" , "McKoy" ) );
people.add( new Person( "Tom" , "Red" ) );
people.toString(): [Person[firstName=John, lastName=McKoy], Person[firstName=Tom, lastName=Red]]
解决方案:
- 克隆 'test' (HashMap
)
- 从 'test' 创建新地图 (HashMap
)
代码如下:
public class ListOfMapJavaApplication2 {
static ArrayList<HashMap> list_test = new ArrayList<HashMap>();
static HashMap<String,String> test =new HashMap<>();
public static void main(String[] args) {
test.put("name", "jhon");
test.put("lastname", "mckoy");
//list_test.add(new HashMap<String,String>(test));
list_test.add((HashMap<String,String>)test.clone());
test.clear();
System.out.println(list_test);
test.put("name", "Tom");
test.put("lastname", "Red");
//list_test.add(new HashMap<String,String>(test));
list_test.add((HashMap<String,String>)test.clone());
}
}
发生这种情况是因为引用调用,您可以使用 new 关键字获取新引用。
import java.util.ArrayList;
import java.util.HashMap;
public class Main
{
static ArrayList<HashMap> list_test = new ArrayList<HashMap>();
static HashMap<String,String> test =new HashMap<>();
public static void main(String[] args) {
test.put("name", "jhon");
test.put("lastname", "mckoy");
list_test.add(test);
test = new HashMap<>();
System.out.println(list_test);
test.put("name", "Tom");
test.put("lastname", "Red");
list_test.add(test);
System.out.println(list_test);
}
}
如果您能帮助我完成以下 Java 代码,我将不胜感激:
import java.util.ArrayList;
import java.util.HashMap;
public class JavaApplication2 {
static ArrayList<HashMap> list_test = new ArrayList<HashMap>();
static HashMap<String,String> test =new HashMap<>();
public static void main(String[] args) {
test.put("name", "jhon");
test.put("lastname", "mckoy");
list_test.add(test);
test.clear();
System.out.println(list_test);
test.put("name", "Tom");
test.put("lastname", "Red");
list_test.add(test);
}
}
我有两个变量,一个叫 list_test (ArrayList),另一个叫 test (HashMap test.clear ();
然后list_test的内容被删除了。为什么?
还有另一种方法来制作 HashMap 列表吗?哪个?
提前致谢
tl;博士
使用您的代码,您放入列表中的同一地图对象就是您清除的同一地图对象。相反,将地图 的 copy 添加到列表中。
listOfMapsOfNames.add( Map.copyOf( mapOfNames ) ); // Make an unmodifiable copy of map to be added to list.
复制您的地图
显然您想要将地图的副本 添加到列表中。
您的代码将原始地图放入列表中。所以现在您有两个对同一个地图的引用:(a) 变量 test
指向地图,并且 (b) 列表中名为 list_test
的第一个元素指向同一个地图对象。如果您使用任何一个引用来更改地图的内容,那么两个引用都会看到该更改,因为它们都指向同一个对象。
或者:
- 调用
Map.copyOf
to make an unmodifiable地图副本。例如:Map.copyOf( oldMap )
- 将映射传递给另一个
Map
实现的构造函数,以将条目复制到新的可修改映射中。例如:new HashMap<>( oldMap )
.
您应该考虑养成在参考文献中使用更通用的超级 class 或接口而不是具体的 class 的习惯。所以 List<Map> list_test
而不是 ArrayList<HashMap> list_test
.
您应该参数化 List
的参数化。所以 List< Map< String, String > >
而不是 List< Map >
.
在您的 Java 标识符上使用更具描述性的名称将使您的代码更易于阅读和调试。所以像 listOfMapsOfNames
而不是 list_test
.
示例代码
这是一些示例代码。
我在地图上删除了 static
并列出,因为它无关紧要。
注意这两个调用 Map.copyOf( mapOfNames )
。
List< Map< String, String > > listOfMapsOfNames = new ArrayList<>() ;
Map< String, String > mapOfNames = new HashMap<>() ;
mapOfNames.put( "name", "John" );
mapOfNames.put( "lastname", "McKoy" );
listOfMapsOfNames.add( Map.copyOf( mapOfNames ) ); // Make an unmodifiable copy of map to be added to list.
System.out.println( "map before clear: " + mapOfNames );
mapOfNames.clear();
System.out.println( "map after clear: " + mapOfNames );
mapOfNames.put( "name", "Tom" );
mapOfNames.put( "lastname" , "Red" );
listOfMapsOfNames.add( Map.copyOf( mapOfNames ) ); // Make an unmodifiable copy of map to be added to list.
System.out.println( "map after 2nd add: " + mapOfNames );
System.out.println( "list at the end: " + listOfMapsOfNames );
看到这个 code run live at IdeOne.com。
map before clear: {name=John, lastname=McKoy}
map after clear: {}
map after 2nd add: {name=Tom, lastname=Red}
list at the end: [{lastname=McKoy, name=John}, {lastname=Red, name=Tom}]
record
与您的问题无关,但供您参考,使用 class 可能比使用 Map
跟踪名字和姓氏更有意义。现在我们有一种更简单的方法来编写这样的 class:records.
records feature is new in Java 16。记录是编写 class 的一种简短方式,其主要目的是透明且不可变地传递数据。编译器隐式创建构造函数、getter、equals
& hashCode
和 toString
。奖励:记录可以在本地声明,也可以嵌套或单独声明。
请注意,使用 record
.
record Person(String firstName , String lastName) {}
List < Person > people = new ArrayList <>();
people.add( new Person( "John" , "McKoy" ) );
people.add( new Person( "Tom" , "Red" ) );
people.toString(): [Person[firstName=John, lastName=McKoy], Person[firstName=Tom, lastName=Red]]
解决方案:
- 克隆 'test' (HashMap
) - 从 'test' 创建新地图 (HashMap
)
代码如下:
public class ListOfMapJavaApplication2 {
static ArrayList<HashMap> list_test = new ArrayList<HashMap>();
static HashMap<String,String> test =new HashMap<>();
public static void main(String[] args) {
test.put("name", "jhon");
test.put("lastname", "mckoy");
//list_test.add(new HashMap<String,String>(test));
list_test.add((HashMap<String,String>)test.clone());
test.clear();
System.out.println(list_test);
test.put("name", "Tom");
test.put("lastname", "Red");
//list_test.add(new HashMap<String,String>(test));
list_test.add((HashMap<String,String>)test.clone());
}
}
发生这种情况是因为引用调用,您可以使用 new 关键字获取新引用。
import java.util.ArrayList;
import java.util.HashMap;
public class Main
{
static ArrayList<HashMap> list_test = new ArrayList<HashMap>();
static HashMap<String,String> test =new HashMap<>();
public static void main(String[] args) {
test.put("name", "jhon");
test.put("lastname", "mckoy");
list_test.add(test);
test = new HashMap<>();
System.out.println(list_test);
test.put("name", "Tom");
test.put("lastname", "Red");
list_test.add(test);
System.out.println(list_test);
}
}