This is my map:
Map<String, Object> params = new HashMap<>();
params.put("topicRef", "update-123456-78925-new-u1z1w3");
params.put("parentRef", "update-123456-78925-new-u1z1w3");
Script script = new Script(ScriptType.INLINE, "painless",
String.format("ctx._source.parentRef = params.parentRef; ctx._source.topicRef = params.topicRef"),
params);
request.setScript(script);
I want to convert my map into a string but I would like to change the pattern for e.g.:
"ctx._source.key = value;ctx._source.key = value"
I want to add to key value a prefix ctx._source.key and a suffix " =" (space and equal), then I would like to separate each entry with a semicolon.
String formattedMap = params.entrySet().
stream()
.map(e -> "ctx._source." + e.getKey() + " = " + e.getValue())
.collect(Collectors.joining(","));
Try something like this:
Map<String, String> yourMap = /*...*/;
StringBuilder bob = new StringBuilder();
yourMap.forEach((key, value) -> bob.append(key).append("=").append(value).append(";"));
String result = bob.toString();
If necessary you could remove the last ; on result via String.concat().
You could stream your Map's entries, then use the map operation to map each entry to the formatted String and ultimately join each element with the collect(Collectors.joining(";")) operation.
Map<String, Object> params = new HashMap<>();
params.put("topicRef", "update-123456-78925-new-u1z1w3");
params.put("parentRef", "update-123456-78925-new-u1z1w3");
String result = params.entrySet().stream()
.map(entry -> String.format("%s%s%s%s", "ctx._source.", entry.getKey(), " =", entry.getValue()))
.collect(Collectors.joining(";"));
System.out.println(result);
Here is a link to test the code
https://www.jdoodle.com/iembed/v0/rrK
Output
String result = params.entrySet()
.stream()
.map(x -> "ctx._source." + x.getKey() + " = " + x.getValue())
.reduce((x, y) -> x + ";" + y).get();
Related
I have a HashMultimap
Multimap<String, String> map = HashMultimap.create();
The data I put into the map is
map.put("cpu", "i9");
map.put("hang", "MSI");
map.put("hang", "DELL");
map.put("hang", "DELL");
map.put("cpu", "i5");
map.put("hang", "HP");
map.put("cpu", "i7");
I have a stream
String joinString = map.entries().stream().map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining(" OR "));
I need the output to be
(hang=HP OR hang=MSI OR hang=DELL) AND (cpu=i9 OR cpu=i5 OR cpu=i7)
I need an AND in between the keys. How can I do that?
Use the Map view:
String joined = map.asMap()
.entrySet()
.stream()
.map(e -> e.getValue()
.stream()
.map(v -> e.getKey() + "=" + v)
.collect(Collectors.joining(" OR ", "(", ")")))
.collect(Collectors.joining(" AND "));
Of course schmosel beat me, but here a slightly different api/usage:
String joined = map.keySet() // keySet() instead of asMap()
.stream().map(k
-> String.format( // string.format instead of concatenation ;)
"(%s)",
map.get(k).stream() // map.get(k) instead of e.getValue()
.map(v
-> String.format("%s=%s", k, v))
.collect(Collectors.joining(" OR "))
)
).collect(Collectors.joining(" AND "));
I want to convert a Stream of a Map<> into a String, to append it to a textArea. I tried some methods, the last with StringBuilder, but they don't work.
public <K, V extends Comparable<? super V>> String sortByAscendentValue(Map<K, V> map, int maxSize) {
StringBuilder sBuilder = new StringBuilder();
Stream<Map.Entry<K,V>> sorted =
map.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()));
BufferedReader br = new BufferedReader(new InputStreamReader((InputStream) sorted));
String read;
try {
while ((read=br.readLine()) != null) {
//System.out.println(read);
sBuilder.append(read);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sorted.limit(maxSize).forEach(System.out::println);
return sBuilder.toString();
}
You can collect the entries into a single String as follows:
String sorted =
map.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.map(e-> e.getKey().toString() + "=" + e.getValue().toString())
.collect(Collectors.joining (","));
Consider slight change to #Eran's code, with regard to the fact that HashMap.Entry.toString() already does joining by = for you:
String sorted =
map.entrySet().stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.map(Objects::toString)
.collect(Collectors.joining(","));
It is easy to do this, you can use the Steams API to do this. First, you map each entry in the map to a single string - the concatenated string of key and value. Once you have that, you can simply use the reduce() method or collect() method to do it.
Code snippet using 'reduce()' method will look something like this:
Map<String, String> map = new HashMap<>();
map.put("sam1", "sam1");
map.put("sam2", "sam2");
String concatString = map.entrySet()
.stream()
.map(element-> element.getKey().toString() + " : " + element.getValue().toString())
.reduce("", (str1,str2) -> str1 + " , " + str2).substring(3);
System.out.println(concatString);
This will give you the following output:
sam2 : sam2 , sam1 : sam1
You can also use the collect()' method instead ofreduce()` method. It will look something like this:
String concatString = map.entrySet()
.stream()
.map(element-> element.getKey().toString() + " : " + element.getValue().toString())
.collect(Collectors.reducing("", (str1,str2) -> str1 + " , " + str2)).substring(3);
Both methods give the same output.
I am new to Java. I have a problem that, I need to Implement the decode(String) method that decodes a String to a corresponding Map. In the assignment, the requirements are like this,
Empty keys and values are allowed, but the equals sign must be present (e.g. "=value", "key=").
If the key or value is empty, empty String should be returned.
If the given String is empty, an empty Map should be returned.
If the given String is null, null should be returned.
Sample Input: one=1&two=2
Should return a Map containing {"one": "1", "two": "2"}
Map<String, String> map = new HashMap<>();
map.put("One", "1");
map.put("Two", "2");
map.put("", "");
map.put("Key", "");
map.put("", "Value");
Set<String> keys = map.keySet();
for(String key : keys) {
System.out.print("\"" + key + "\"" + ":" + "\"" + map.get(key) + "\"");
}
My piece of code is giving output as required, But I have implemented this in the main method with Map<K, V> interface, while I need to write code that takes String as a parameter and decodes to Map.
Thanks
One solution could be:
public Map<String, String> parseMap(String mapString) {
if (mapString == null || mapString.isEmpty()) {
return Collections.emptyMap();
}
return Arrays.stream(mapString.split("&"))
.map(this::splitParam)
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
}
public AbstractMap.SimpleEntry<String, String> splitParam(String it) {
final int idx = it.indexOf("=");
final String key = it.substring(0, idx);
final String value = it.substring(idx + 1);
return new AbstractMap.SimpleEntry<>(key, value);
}
usage
String inputString = "one=1&two=2";
Map<String, String> map = parseMap(inputString);
//your code to print the map again
Set<String> keys = map.keySet();
for(String key : keys) {
System.out.print("\"" + key + "\"" + ":" + "\"" + map.get(key) + "\"");
}
try this in your editor, just 4 lines :)
String input = "one=1&two=2";
String[] kvs = input.split("&");
Map<String, String> hashMap = Stream.of(kvs)
.collect(Collectors.toMap(item -> item.split("=")[0],
item -> item.split("=")[1]));
hashMap.forEach((k, v) -> System.out.println(k + ":" + v));
This question already has answers here:
How to convert map to url query string?
(20 answers)
Closed 4 years ago.
I want to create util method which converts HashMap into long String with keys and values:
HashMap<String, String> map = new LinkedhashMap<>();
map.put("first_key", "first_value");
map.put("second_key", "second_value");
I need to get this end result:
first_key=first_value&second_key=second_value
You can use streams:
String result = map.entrySet().stream()
.map(e -> e.getKey() + "=" + e.getValue())
.collect(Collectors.joining("&"));
Note: You should probably use an url encoding. First create a helper method like this:
public static String encode(String s){
try{
return java.net.URLEncoder.encode(s, "UTF-8");
} catch(UnsupportedEncodingException e){
throw new IllegalStateException(e);
}
}
And then use that inside of your stream to encode the key and value:
String result = map.entrySet().stream()
.map(e -> encode(e.getKey()) + "=" + encode(e.getValue()))
.collect(Collectors.joining("&"));
Try this:
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : map.entrySet()) {
sb.append(entry.getKey());
sb.append('=');
sb.append(entry.getValue());
sb.append('&');
}
sb.deleteCharAt(sb.length() - 1);
String result = sb.toString();
map.toString().replace(",","&")
The output Map::toString is not much different from the output you want. Compare:
{first_key=first_value, second_key=second_value}
first_key=first_value&second_key=second_value
Just perform the right character replacement:
map.toString().replaceAll("[{ }]", "").replace(",","&")
"[{ }]" is regex matching all the brackets {} and the space - those to be removed (replaced with "").
, to be replaced with & character.
I have written the following code:
String reqParams = null;
Map<String, String[]> params = request.getParameterMap();
for (Object key : params.keySet()) {
String keyStr = (String) key;
String[] value = params.get(keyStr);
reqParams = reqParams + ((String) key + "=" + Arrays.toString(value) + " ");
}
System.out.println(reqParams);
I have the following output:
nullorderId=[01] orderStatus=[delivered]
How can I get rid of the null that prints at the beginning?
Is it possible to avoid the [ ] from printing?
How can I do this using streams?
Use map operation and the joining collector:
String resultSet =
params.entrySet()
.stream()
.map(e -> e.getKey() + "=" + String.join(", ", e.getValue()))
.collect(Collectors.joining(" "));
", " is the delimiter if the array has more than one element.
" " in the joining is the delimiter to separate the elements
from the source.
Initialize reqParams as an empty string. That is,
String reqParams = null;
becomes
String reqParams = "";
Initialize reqParams like this : String reqParams = "" or don't append your string to redParams and just do this reqParams = ((String) key + "=" + value[0] + " ");
Just get the element in the array instead of turning the array into a String: reqParams = reqParams + ((String) key + "=" + value[0] + " ");
You could stream params.keySet().stream().forEach(key -> .... ) and add a function in the forEach that appends the key and the value to a String like you're doing in the for loop.
You could use the join method of the String class to turn the array into a String, avoiding the [ ] characters. Also, you don't need all the casting and extra parentheses that you have in your original code, if you use Map.Entry with type parameters, and iterate through the entry set instead of the key set.
for( Map.Entry<String,String[]> entry : params.entrySet()) {
reqParams = reqParams + entry.getKey() + "=" + String.join(",", entry.getValue()) + " ";
}
So here, join takes your array and separates all the elements with commas.
Lastly, if you initialise reqParams to "" instead of null, then the word null won't print.
String reqParams = "";