I have a Map
shown below:
Map<Character, Integer> map = new LinkedHashMap<Character, Integer>();
map.put('c', 5);
map.put('f', 2);
map.put('r', 1);
map.put('D', 3);
I need to obtain the output:
cccccffrDDD
I can do it in normal process, but I want to do it in Java 8. Can you share some hints how to achieve this?
CodePudding user response:
Is this what you need?
Map<Character, Integer> map = new LinkedHashMap<Character, Integer>();
map.put('c',5);
map.put('f', 2);
map.put('r', 1);
map.put('D', 3);
StringBuilder sb = new StringBuilder();
map.forEach((k,v)->{
sb.append(String.valueOf(k).repeat(v));
});
System.out.print(sb);
Notice that the repeat method is only avaliable above Java 11.
For Java 1.8 version
StringBuilder sb = new StringBuilder();
map.forEach((k,v)->{
for(int i=0; i<v; i ) {
sb.append(k);
}
});
System.out.print(sb);
CodePudding user response:
You can use forEach() and StringBuilder to compose.
StringBuilder sb = new StringBuilder();
map.forEach((k,v) -> {
for (int i = 0; i < v; i ) {
sb.append(k);
}
});
CodePudding user response:
You can stream the entry set of the map and print the key with its value as factor using String.repeat(int count)
(introduced in Java 11), maybe as follows:
public static void main(String[] args) {
Map<Character, Integer> map = new LinkedHashMap<Character, Integer>();
map.put('c',5);
map.put('f', 2);
map.put('r', 1);
map.put('D', 3);
// stream the set of entries and repeat the (String version of the) key value-times
map.entrySet().forEach(e -> System.out.print(e.getKey().toString().repeat(e.getValue())));
}
This prints
cccccffrDDD
CodePudding user response:
When you are using Java 8, which doesn’t have the String.repeat(…)
method, you may use
String result = map.entrySet().stream()
.map(e -> {
char[] array = new char[e.getValue()];
Arrays.fill(array, e.getKey());
return CharBuffer.wrap(array);
})
.collect(Collectors.joining());
or use a custom collector:
String result = map.entrySet().stream()
.collect(Collector.of(
StringBuilder::new,
(sb, e) -> { for(int i = e.getValue(); i > 0; i--) sb.append(e.getKey()); },
StringBuilder::append,
StringBuilder::toString));
CodePudding user response:
Here's a couple of ideas on how to approach this problem using Java 8 streams.
The overall idea:
- create a stream of map entries;
- generate a stream of single-letter strings based on each entry and merge them using built-in collector
joining()
; - apply collect with collector
joining()
to obtain the final result.
String joinedLetters = map.entrySet().stream()
.map(entry -> Stream.generate(() -> String.valueOf(entry.getKey()))
.limit(entry.getValue())
.collect(Collectors.joining()))
.collect(Collectors.joining());
Another way of achieving this:
- create a stream of entries;
- create a lightweight list of Strings using
Collections.nCopies()
; - turn each list into a
String
using static methodString.join()
; - combine the strings together using collector
joining()
.
String joinedLetters = map.entrySet().stream()
.map(entry -> Collections.nCopies(entry.getValue(), String.valueOf(entry.getKey())))
.map(list -> String.join("", list))
.collect(Collectors.joining());
Use this link to play around with Online demo
CodePudding user response:
As mentioned above, you can build the string by using the lambda expression as follows.
StringBuilder output = new StringBuilder();
map.forEach((k, v) -> {
for (int i = 0; i < v; i ) {
output.append(k);
}
});
Or you can replace the standard with IntStreams.
StringBuilder output = new StringBuilder();
map.forEach((k, v) -> IntStream.range(0, v).forEach(i -> b.append(k)));