Java: Counting Char Occurance in a Arraylist [closed]

I’m trying to find a way to add the char and its value together from an array list.

The List I have is = [A, Q3, Q, Z2, B2, C2, B4]

It is possible to return the Array list in this way using regex Pattern and regex Matcher. I’m trying to make it look like this :

A = 1, B = 6, C = 2, Q = 4, Z = 2,

Kind Regards

Answer

var in = List.of("A", "Q3", "Q", "Z2", "B2", "C2", "B4");

Map<String, Integer> values =
 in.stream().collect(Collectors.toMap(
   s -> s.substring(0, 1),
   s -> s.length() == 1 ? 1 : Integer.parseInt(s.substring(1)),
   (a, b) -> a + b,
   () -> new TreeMap<>()));

System.out.println(values);

> {A=1, B=6, C=2, Q=4, Z=2}

Piece by piece:

in.stream() – We want to use the stream API to modify the contents of the list

.collect – We want to take the data; there is no need to transform or filter any of these items, we want all of it, collected into a new data type

toMap – specifically, a Map, which maps some key (such as B) to some value (such as 6).

We then pass 4 arguments.

  • Arg 1, the ‘keyMapper’: s -> s.substring(0, 1)

This says: To obtain the key (the ‘B’ in the mapping B maps to 6), take any of the input strings, and reduce it to just the first character.

  • Arg 2, the ‘valueMapper’: s -> s.length == 1 ? 1 : Integer.parseInt(s.substring(1))

This says: To obtain the value, first check if the length of the string is just 1, in that case the value is 1. Otherwise, lop off the first character and then parse the rest as a number

  • Arg3, the ‘merge’ function: (a, b) -> a + b.

To merge any 2 values (such as the 3 from "Q3" and the 1 from "Q"), do so by adding them.

  • Arg4: The map supplier: () -> new TreeMap<>()

We all want this to be put into a new map of type TreeMap; TreeMaps keep themselves automatically sorted on the key. This means the ‘A=1’ pair is first in the map, then B, then C, etcetera. The <> tell java to automatically figure out what keys and values this map should have (Strings to Integers, derived automatically because of the keyMapper and valueMapper functions).

If this looks unfamiliar to you, arg -> code; means: This is a function that takes in the stated args and then runs the code. It hands that function off (without running it; it’s up to the code you hand this function to, to run it). () is ‘no arguments’.

If you want to take the resulting map and produce that exact string…

String r = map.entrySet().stream()
  .map(x -> x.getKey() + " = " + x.getValue() + ", ")
  .collect(Collectors.joining());
System.out.println(r);
> A = 1, B = 6, C = 2, Q = 4, Z = 2,

Though I’m not sure why you’d want to do that.

.map() turns a stream of foos into bars, here we say: Take a map entry (an object where .getKey() gives you "B" and .getValue() gives you 6 for example), and turn it into a string by running the code "B" + " = " + 6 + ", ", thus making "B = 6, ".

.collect(Collectors.joining()) means: Turn this stream of strings into a single string by just concatenating the lot, in order.