简体   繁体   English

添加到列表后清除 HashMap,在 Java

[英]Clear a HashMap after adding to a List, in Java

I would be very grateful if you could help me with the following Java code:如果您能帮助我使用以下 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);
        
    }
    
}

I have two variables one called list_test (ArrayList ) and another called test (HashMap <String, String>).我有两个变量,一个叫做 list_test (ArrayList),另一个叫做 test (HashMap <String, String>)。 My goal is to make a ArrayList of HashMap using the following code, but after executing: test.clear ();我的目标是使用以下代码制作 HashMap 的 ArrayList,但在执行后: test.clear (); then the content of list_test is deleted.然后 list_test 的内容被删除。 Why?为什么? Is there another way to make a HashMap list?还有其他方法可以制作 HashMap 列表吗? Which?哪个?

Thanks in advance提前致谢

tl;dr tl;博士

With your code, the same map object that you put in the list is the same map object that you clear.使用您的代码,您放入列表中的 map object 与您清除的 map ZA8CFDE6331BD59EB66AC96F8911 相同。 Instead, add a copy of your map into your list.相反,将您的 map 的副本添加到您的列表中。

listOfMapsOfNames.add( Map.copyOf( mapOfNames ) );  // Make an unmodifiable copy of map to be added to list.

Make a copy of your map复制您的 map

Apparently you want a copy of your map added to the list.显然,您希望将 map 的副本添加到列表中。

Your code puts the original map into the list.您的代码将原始 map 放入列表中。 So now you have two references to the same map: (a) the variable test points to the map, and (b) the first element in the list named list_test points to the very same map object. So now you have two references to the same map: (a) the variable test points to the map, and (b) the first element in the list named list_test points to the very same map object. If you use either reference to change the map's contents, both references see that change, given that they both point to the same object .如果您使用任一引用来更改地图的内容,则两个引用都会看到该更改,因为它们都指向相同的 object

Either:任何一个:

  • Call Map.copyOf to make an unmodifiable copy of the map.调用Map.copyOf以制作 map 的不可修改副本。 Ex: Map.copyOf( oldMap )例如: Map.copyOf( oldMap )
  • Pass the map to the constructor of another Map implementation to copy the entries over to a new modifiable map.将 map 传递给另一个Map实现的构造函数,以将条目复制到新的可修改 map。 Ex: new HashMap<>( oldMap ) .例如: new HashMap<>( oldMap )

You should consider making a habit of using the more general superclass or interface rather than concrete class in your references, where practical.在实用的情况下,您应该考虑养成在参考文献中使用更通用的超类或接口而不是具体的 class 的习惯。 So List<Map> list_test rather than ArrayList<HashMap> list_test .所以List<Map> list_test而不是ArrayList<HashMap> list_test

You should parameterize the parameterization of your List .您应该参数化List的参数化。 So List< Map< String, String > > rather than List< Map > .所以List< Map< String, String > >而不是List< Map >

Using more descriptive names on your Java identifiers will make your code easier to read and debug.在 Java 标识符上使用更具描述性的名称将使您的代码更易于阅读和调试。 So something like listOfMapsOfNames rather than list_test .所以像listOfMapsOfNames而不是list_test

Example code示例代码

Here is some example code.这是一些示例代码。

I dropped the static on the map and list as that is irrelevant.我将static放在 map 上并列出,因为这无关紧要。

Notice the two calls Map.copyOf( mapOfNames ) .注意两个调用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 );

See this code run live at IdeOne.com .请参阅在 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

Not relevant to your Question, but for your information, the use of a class might make more sense than using a Map for tracking first name and last name.与您的问题无关,但为了您的信息,使用 class 可能比使用Map跟踪名字和姓氏更有意义。 And now we have an easier way to write such a class: records .现在我们有了更简单的方法来编写这样的 class: records

The records feature is new in Java 16 .记录功能是Java 16中的新功能。 A record is a brief way to write a class whose main purpose is to communicate data transparently and immutably.记录是编写 class 的简要方法,其主要目的是透明且不可变地传递数据。 The compiler implicitly creates the constructor, getters, equals & hashCode , and toString .编译器隐式创建构造函数、getter、 equals & hashCodetoString Bonus: A record can be declared locally as well as being declared nested or separate.奖励:记录可以在本地声明,也可以声明为嵌套的或单独的。

Notice the following version of your code becomes more expressive (and shorter) with record .请注意,您的代码的以下版本使用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]] people.toString(): [Person[firstName=John, lastName=McKoy], Person[firstName=Tom, lastName=Red]]

Solution:解决方案:

  1. clone of 'test' (HashMap<String,String>) 'test' 的克隆 (HashMap<String,String>)
  2. create new Map from 'test' (HashMap<String,String>)从“测试”(HashMap<String,String>)创建新的 Map

Here is the code:这是代码:

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());

    }
}

this is happing because of call by reference you can take new reference using the new keyword.这是因为引用调用而发生的,您可以使用 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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM