I am trying to understand Collections and Stream.
I have split the sentence below and kept the position of each letter (I ignored space/blank): “Hello Word!”
private static final String text = "Hello Word!"; static Map<String, List<Integer>> charsIndex = new HashMap<>(); static void charsIndex() { List<Character> charsList = text .chars() .mapToObj(e -> (char) e) .toList(); System.out.println(charsList); int position = 0; for (Character c : charsList) { if(!c.toString().isBlank()){ charsIndex.computeIfAbsent(c.toString(), addCharPosition -> new ArrayList<>()).add(position); } position += 1; } System.out.println(charsIndex); }
Results:
[H, e, l, l, o, , W, o, r, d, !] (charsList)
{!=[10], r=[8], d=[9], e=[1], W=[6], H=[0], l=[2, 3], o=[4, 7]} (charsIndex)
How can I sort the characters and rebuild my word along with the blank?
I try this way:
static void charsToString(){ charsIndex.forEach((character, l) -> l.forEach(position -> { })); }
Advertisement
Answer
You can restore the original string based on the map of indices in the following steps:
Sort the characters according to their positions. Because each entry in the map associates a character with multiple indices, for that you would need to define an auxiliary type, holding a reference to a single-char string and distinct position of this character. Let’s call it
CharPosition
Generate a list of
CharPosition
(which is sorted).To restore the white spaces, we can define an array, having a length of the highest index + 1. Then populate this array with the contents of the
CharPosition
list.Finally, create a stream over the array elements, replace all null values with a white space and generate the resulting
String
using Collectorjoining()
.
For the purpose of conciseness, I’ll use a Java 16 record to implement CharPosition
:
public record CharPosition(String ch, int pos) {}
That’s how the logic described above can be implemented:
static void charsToString() { List<CharPosition> charPositions = charsIndex.entrySet().stream() .flatMap(entry -> entry.getValue().stream() .map(pos -> new CharPosition(entry.getKey(), pos)) ) .sorted(Comparator.comparingInt(CharPosition::pos)) .toList(); int wordLen = charPositions.get(charPositions.size() - 1).pos() + 1; String[] word = new String[wordLen]; charPositions.forEach(c -> word[c.pos()] = c.ch()); String result = Arrays.stream(word) .map(str -> Objects.requireNonNullElse(str, " ")) .collect(Collectors.joining()); System.out.println(result); }
Output:
Hello Word!