1

Suppose I have a String "abca". I want to keep track of each alphabet occurrence in every index using HashMap & ArrayList in Java. For example if a=0,b=1,c=2, I want the output like below: for input: abca

[{0=1},{0=1, 1=1},{0=1, 1=1, 2=1},{0=2, 1=1, 2=1}];

I have written this solution in Java:

public static void main(String[] args){
     Scanner in = new Scanner(System.in);

     String x = in.next();
     char a[] = x.toCharArray();
     HashMap<Integer,Integer> hm = new HashMap();
     ArrayList<HashMap<Integer,Integer>> list = new ArrayList();

     for(int i=0;i<a.length;i++){
         if(hm.get((int)a[i]-97)==null){
             hm.put((int)a[i]-97, 1);
         }
         else{
             int pow = hm.get((int)a[i]-97);
             pow++;
             hm.put((int)a[i]-97, pow);
         }
         list.add(hm);
        // System.out.println(list);
     }
     System.out.println(list);
}

But I am getting output as:

[{0=2, 1=1, 2=1}, {0=2, 1=1, 2=1}, {0=2, 1=1, 2=1}, {0=2, 1=1, 2=1}]

At the end of the iteration, ArrayList is updating all the indices of the last stage of HashMap.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • 1
    Does this answer your question? [Is Java "pass-by-reference" or "pass-by-value"?](https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value) – jhamon Feb 25 '20 at 16:15
  • Just curious as to what you really want. Are you doing a frequency count of letters in the string? I don't understand why you want to create a `list of maps`. – WJS Feb 25 '20 at 16:55

2 Answers2

2

The original map will be mutated in every iteration, so to fix this you need to create a new HashMap and add it in every iteration.

list.add(new HashMap<>(hm));

output:

[{0=1}, {0=1, 1=1}, {0=1, 1=1, 2=1}, {0=2, 1=1, 2=1}]

Govinda Sakhare
  • 5,009
  • 6
  • 33
  • 74
1

Well, if you're interested, you can also do it like this.

         Scanner in = new Scanner(System.in);
         String x = in.next();
         char a[] = x.toCharArray();
         List<HashMap<Integer, Integer>> list = new ArrayList<>();
         HashMap<Integer, Integer> hm = new HashMap<>();

         for (char c : a) {
             hm.compute(c-'a', (k,v) -> v == null ? 1 : ++v);
             list.add(new HashMap<>(hm));
         }

         System.out.println(list);

The hm.compute() method looks for the value for the supplied key.

  • if null, it initializes to 1.
  • otherwise it increments the value by 1
WJS
  • 36,363
  • 4
  • 24
  • 39