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 -> {
}));
}
CodePudding user response:
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!