简体   繁体   English

Java:HashMap <String,String> 存储与键和值相同的值。

[英]Java:HashMap<String,String> storing same value as key and value.?

I am getting this strange output in HashMap . 我在HashMap得到了这个奇怪的输出。

I have two ArrayList<String> one containing the key and another containing value. 我有两个ArrayList<String>一个包含键,另一个包含值。

My HashMap<String,String> will store only string as key and value pair. 我的HashMap<String,String>仅将字符串存储为键和值对。 But key itself is getting stored in value. 但是,密钥本身已存储在价值中。 I have checked my value arraylist, it's printing the value. 我已经检查了我的值arraylist,它正在打印值。 But during putting it's setting it as key itself. 但是在放置过程中,它会将其自身设置为关键。

Code snippet is: 代码段是:

public HashMap<String,String> getLstBarring()
    {
        ArrayList<String> temparrLst=setPreParameters(fetchPreDetails, 1);
        System.out.println("KEY"    +  temparrLst);

        ArrayList<String> tempArrLstId=setPreParameters(fetchPreDetails, 14);
        System.out.println("VALUE"      +tempArrLstId);
        int length=tempArrLstId.size();

        for(int index=0;index<length;index++)
        {
            System.out.println("VALUE IN KEY"   +  temparrLst.get(index));
            System.out.println("VALUE IN VALUE"   +   tempArrLstId.get(index));
            this.lstBarring.put(temparrLst.get(index), tempArrLstId.get(index));
        }
        System.out.println("INSIDE ODB....>>>>>>>>>>>>>>"   + lstBarring);

    return this.lstBarring;
    }

Problem is: 问题是:

  • 1st SOP is KEY-printing all the key correctly. 1st SOP正在正确打印所有密钥。
  • 2nd SOP is VALUE-printing all the value correctly. 第2个SOP为VALUE-正确打印所有值。
  • 3rd SOP is VALUE IN KEY----printing all the values. 第三个SOP是键中的值-打印所有值。
  • 4th SOP is VALUE IN VALUE--printing all the values. 第四个SOP是VALUE IN VALUE-打印所有值。

Hence after ever iteration I am getting value,value in HashMap whereas it should be key,value. 因此,在迭代之后,我在HashMap获得了value,value,而它应该是key,value。

Here's look at my Method:- 这是我的方法:-

public ArrayList<String> setPreParameters(HashMap<Integer,String> fetchPreDetails,int index)
    {   
        switch(index)
        {

        case 1:
        {
            arrLstData.clear();
            splittedString=fetchPreDetails.get(1).split(",");
            Collections.addAll(arrLstData, splittedString); 
            break;

        }

return arrLstData;

Please guide me as to where am I going wrong. 请告诉我我要去哪里错了。

My guess is that either fetchPreDetails is a collection being mutated by setPreParameters() or else setPreParameters() is mutating some other shared state so that the collection referenced by your temparrLst is being changed on the second call to setPreParameters() . 我的猜测是,要么fetchPreDetails是由setPreParameters()突变的集合,要么fetchPreDetails setPreParameters()突变了其他共享状态,以便您的temparrLst引用的集合在第二次调用setPreParameters()被更改。 Ie

List<String> strings = new ArrayList();
strings.add("a");
strings.add("b");
List<String> otherStrings = strings;
otherStrings.add("c");

I expect your code assumes that strings would contain "a" and "b" and that otherStrings would contain "a", "b", and "c". 我希望您的代码假定strings将包含“ a”和“ b”,而otherStrings将包含“ a”,“ b”和“ c”。 This isn't how object references work in Java. 这不是Java中对象引用的工作方式。 The line List<String> otherStrings = strings; List<String> otherStrings = strings; makes both strings and otherStrings point to the same collection, and thus changes made using either name affect the same thing. 使stringsotherStrings指向同一集合,因此使用这两个名称所做的更改都会影响同一件事。

Edit: Your newly-posted code seems to prove my hypothesis. 编辑:您新发布的代码似乎证明了我的假设。 You have a variable called arrLstData that you clear, populate, and return on each call to setPreParameters() . 您有一个名为arrLstData的变量,您可以在每次调用setPreParameters()清除,填充并返回该变量。 You're returning the same collection every time you call this method. 每次调用此方法都将返回相同的集合。 Therefore you just have multiple handles to the same collection instead of multiple collections. 因此,您只有同一个集合的多个句柄,而不是多个集合。 You need to create a new collection and return it each time you call setPreParameters() . 您需要创建一个新集合,并在每次调用setPreParameters()时将其返回。

Edit again: Maybe this will make it clearer. 再次编辑:也许这样会使它更清晰。 Here's what you're doing: 这是您正在做的事情:

public static void main(String[] args) {
    Foo f = new Foo();
    List<String> list1 = f.getList("a", "b");
    System.out.println(list1);
    List<String> list2 = f.getList("c", "d");
    System.out.println(list2);
    System.out.println(list1);
}

static class Foo {
    private List<String> myList = new ArrayList<String>();
    public List<String> getList(String... strings) {
        myList.clear();
        myList.addAll(Arrays.asList(strings));
        return myList;
    }
}

Note that this exhibits exactly the behavior that you're describing, and the correct way to solve it is something like this: 请注意,这完全体现了您正在描述的行为,而解决此问题的正确方法是这样的:

public static void main(String[] args) {
    Foo f = new Foo();
    List<String> list1 = f.getList("a", "b");
    System.out.println(list1);
    List<String> list2 = f.getList("c", "d");
    System.out.println(list2);
    System.out.println(list1);
}

static class Foo {
    public List<String> getList(String... strings) {
        List<String> result = new ArrayList<String>();
        result.addAll(Arrays.asList(strings));
        return result;
    }
}

You are reusing the same List over and over at your setPreParameters Method. 您正在setPreParameters方法中反复使用相同的List。
The List in arrLstData is returned and stored in temparrLst , now you are clearing the the Lists content, putting new stuff in it and storing it to tempArrLstId . 返回arrLstData的List并将其存储在temparrLst ,现在您正在清除Lists内容,将新内容放入其中并将其存储到tempArrLstId
Now the three variables all contain the very same list (they are not equals, its the same!). 现在这三个变量都包含完全相同的列表(它们不等于,相同!)。
There is only one List object at the whole example! 整个示例中只有一个List对象!

Its like you got a box and label it "A" on one side put stuff in it, label it "B" on another side and wondering why the box "B" is empty when you turn box "A" upside-down. 就像您有一个盒子,并在一侧将其标记为“ A”,然后在其中放入东西,在另一侧将其标记为“ B”,并且想知道当您将盒子“ A”倒置时为什么盒子“ B”是空的。

Did you maybe mean something like this? 您可能是这样说的吗?

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class GlobalsMess {

    private Map<String, String> lstBarring = new HashMap<String, String>();
    private Map<Integer, String> fetchPreDetails = new HashMap<Integer, String>();

    public GlobalsMess() {
        fetchPreDetails.put(1, "john,vikam,david");
        fetchPreDetails.put(14, "1,2,3");
    }

    public Map<String, String> getLstBarring() {

        List<String> tempKeys = setPreParameters(fetchPreDetails.get(1));
        System.out.println("KEY" + tempKeys);

        List<String> tempIds = setPreParameters(fetchPreDetails.get(14));
        System.out.println("VALUE" + tempIds);

        for (int index = 0; index < tempIds.size(); index++) {
            System.out.println("VALUE IN KEY" + tempKeys.get(index));
            System.out.println("VALUE IN VALUE" + tempIds.get(index));
            this.lstBarring.put(tempKeys.get(index), tempIds.get(index));
        }
        System.out.println("INSIDE ODB....>>>>>>>>>>>>>>" + lstBarring);

        return this.lstBarring;
    }

    public List<String> setPreParameters(String fetchPreDetailsValue) {
        List<String> arrLstData = new ArrayList<String>();
        Collections.addAll(arrLstData, fetchPreDetailsValue.split(","));
        return arrLstData;
    }

    public static void main(String[] args) {
        new GlobalsMess().getLstBarring();
    }
}

Output: 输出:

KEY[john, vikam, david]
VALUE[1, 2, 3]
VALUE IN KEYjohn
VALUE IN VALUE1
VALUE IN KEYvikam
VALUE IN VALUE2
VALUE IN KEYdavid
VALUE IN VALUE3
INSIDE ODB....>>>>>>>>>>>>>>{david=3, vikam=2, john=1}

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

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