Filter out unwanted string in map - java

EDIT:
I have string like this:
String value1 = "xyzz###$%helloworldtestdata"
or
String value1 = "xyzztestcase" or String value1 = "notincludedxyzztestcase"
and
String value2 = "xxxyz! xyyz xyzz xyyz"
I am trying to filter out each string with their corresponding word. So far, I have this code and it was fine but not with the value1
Map<String, String> map = new HashMap<String, String>();
map.put("xxxyz!", "test1");
map.put("xxxyz?", "test2");
map.put("xyyz", "test3");
map.put("xyzz", "test4");
for (String s : map.keySet()) {
if (value2.contains(s)) {
value2 = value2.replaceAll(s, map.get(s));
}
}
If I use the value2 here is the output I am getting:
test1 test3 test4 test3
But if I use the value1 I am getting this one:
test4###$%helloworldtestdata
How can I filter out the part that is not included on my map, key but not messing the spaces of value1?

The replaceAll method is simply taking whatever your value for s (the keys in your map) is and replacing it with your value for s in your map. From what you described, something similar to what you want to do is do a
value2 = value2.replaceAll("###$%helloworldtestdata", "");
This will replace the string ###$%helloworldtestdata with an empty one.
To do this reassignment in your method, you would want to add the following to your map:
map.put("###$%helloworldtestdata", "test5");
(test5 is just an example)
Adding this will not mess up your spaces in value1 because the string it looking to replace (the regex) has not been changed for any of the other strings you are looking for.

i dont know about i use, but here i use in my code.
var = "how to set love"
i just use one set to get value i want.
print var[:2]
is wil get "how"
and yes if you fil replace just use
x = var.replace("i will be", "how to")
it will get "i will be set love"
correct me if i flase 😁

Related

Java 8 Optional parse string to int or if is null and set default empty string

I'm trying to parse string to int and set as default an empty string if the string is null with lambda. Here is my code:
Map<String, Object> myMap = new HashMap<>();
String myString = "Some String"; //can be also null
myMap.put("myData", Optional.ofNullable(myString).map(Integer::parseInt).orElse(""));
...
The Problem is that i should to set an Integer in .orElse() as default but I need to set and empty string. I know I can do this with java like this:
myMap.put("myData", StringUtils.isEmpty(myString) ? "" : Integer.parseInt(myString));
but I want do that with lambda.
Can someone help me with that?
It’s fairly straightforward. We just need to tell the stream pipeline to consider the Integer an Object, not an Integer. And oh yes, then the string needs to hold a number when it is not null.
Map<String, Object> myMap = new HashMap<>();
String myString = "53"; //can be also null
myMap.put("myData",
Optional.ofNullable(myString)
.map(s -> (Object) Integer.valueOf(s))
.orElse(""));
System.out.println(myMap);
This outputs:
{myData=53}
And if I change this line:
String myString = null; //can be also non-null
{myData=}
You do not need to use an Optional, and some would prefer that you don’t. Here’s a variant without it:
myMap.put("myData", myString == null ? "" : Integer.valueOf(myString));
The result is the same as before. Do you agree that it’s simpler?

replace specific word after specific char in java

I have this String
String tst = " {"id":$.id, "parent_id":200}";
I am trying to extract $.id from this string and replace it by an other word.
For now I tried:
tst = tst.replaceAll("(\\$.).", "other_word");
But this code is replacing all the rest (like "parent_id"...) by this other word
here is the output:
{"id":other_wordd_mag, "parent_id":200}
it's replacing only the "i" from "id_mag" any solution ?
This code seems to be replacing as expected:
String tst = " {\"id\":$.id, \"parent_id\":200}";
System.out.println(tst.replaceAll("\\$\\.id", "other_word"));
Output:
{"id":other_word, "parent_id":200}
Update
If you need to substitute some variables inside JSON, you can use the following regexp:
String tst = "{\"id\":$.id, \"name\":$.name, \"parent_id\":200}";
System.out.println(tst.replaceAll("(\\$\\.\\w+)", "\"other_word\"")); // using shorthand for word characters
output:
{"id":"other_word", "name":"other_word", "parent_id":200}
Or, if you have a map of variables in the form of key-value pairs, you can use this method:
static String replaceVars(String src, Map<String, String> vars) {
for (Map.Entry<String, String> e : vars.entrySet()) {
src = src.replaceAll("(\\$\\." + e.getKey()+ ")", "\"" + e.getValue()+"\"");
}
return src;
}
// -----------
String tstDiff = "{\"id\":$.id, \"name\":$.name, \"parent_id\":200}";
System.out.println(replaceVars(tstDiff, Map.of("id", "my_id", "name", "my_name")));
output:
{"id":"my_id", "name":"my_name", "parent_id":200}
Working with these types of strings can be a little bit easier if you know what JSON is.
And Java has also a really good library for handling Json strings called GSON.
You can use this library and for this specific case use the fromJson method.
But if you want to work with regex and get familiar with Strings:
tst.replaceAll("\\$\\.id", "other_word")
This should work properly.

Insert string keyword values based map keys in main string

In Java, I have to insert strings value based on the key in main string.
For example -
Main String -
sellers(seller: $sellerId, shipment: $shipmentId)
Map of key and value -
{
sellerId: abc
shipmentId: 123
}
So after inserting it will become
sellers(seller: abc, shipment: 123)
I know i can do string replace. But that doesn't seem to be good approach here. So just wondering is there a standard approach or better way of doing things here?
Two approaches you can consider:
1 - loop over map entries, and do a simple string replace (note that this assumes a single occurrence of each var in the strings; if that is not the case, you need to use replaceAll):
String text = "sellers(seller: $sellerId, shipment: $shipmentId)";
Map<String, Object> binding = ...;
String result = text;
for (Entry<String, Object> entry : binding.entrySet()) {
result = result.replace("$" + entry.getKey(), String.valueOf(entry.getValue()));
}
2 - for advanced use cases, you want to use a proper template engine. And here's an example using groovy's simple template engine (use in java by adding the groovy jar):
groovy.text.SimpleTemplateEngine engine = new groovy.text.SimpleTemplateEngine();
Writable template = engine.createTemplate(text).make(binding);
String result = template.toString();
Just note that groovy replaces variable names prefixed with $, and that's why this works without changes (making this a good choice for your current syntax).
Both produce your expected result, but you have to choose based on what this can turn into.
Depending on values map can hold you may face some problems. For instance if value may contain other key identifier like
{
foo: $bar
bar: 123
}
then using series of replace(mapEntryKey, mapEntryValue) could change string like
abc $foo efg $bar
first into $foo->$bar
abc $bar efg $bar
and then $bar->123
abc 123 efg 123
which is NOT what we wanted.
To avoid such problem we should iterate over template only once, search for each $key and replace it with value stored for it in map. If map doesn't contain such key we can leave it as it (replace it with itself).
We can do it with Matcher#replaceAll​(Function<MatchResult,​String> replacer). BTW if map value can contain $ and \ which are also metacharacters in replacement, we need to escape them. To do it we can use Mather#quoteReplacement method.
Demo:
Map<String, String> map = Map.of("sellerId", "abc",
"shipmentId", "123");
String yourTemplate = "sellers(seller: $sellerId, shipment: $shipmentId)";
Pattern p = Pattern.compile("\\$(\\w+)");
Matcher m = p.matcher(yourTemplate);
String replaced = m.replaceAll(match -> {
if(map.containsKey(match.group(1))){
return Matcher.quoteReplacement(map.get(match.group(1)));
}else{
return Matcher.quoteReplacement(match.group());
}
});
System.out.println(replaced);
Output: sellers(seller: abc, shipment: 123).
String format is an option here
Map<String, Integer> yourMap = new HashMap<>();
yourMap.put("abc", 123);
for (Map.Entry<String, Integer> entry : yourMap.entrySet()) {
String output = String.format("sellers(seller: %s, shipment: %d)", entry.getKey(), entry.getValue());
System.out.println("output = " + output);
}

Replacing values inside curly brackets with parameters

Let's say i have a string like this: "/c1/client/{clientId}/field/{fieldId}/version/{versionId}/file/{filename}"
I want to replace all values inside curly brackets with the actual values, so the link would look like this:
"c1/client/Tudor/field/search/version/1/file/hello.txt".
How can i do that in a way that does not limit the number of parameters used? Because i have some requests with 4 parameters (like this one) and others with only one parameter, or none. What is the best way to do this?
Edit: I would need something like: Search string for any values between {}. If string contains {value}, take all {values} and replace with parameter.
You can parse #pathParameters and redirect to the address you create with spring #controller. If these are request as you wrote that is the right approach.
In case of String:
var u = "/c1/client/{clientId}/field/{fieldId}/version/{versionId}/file/{filename}";
u.replace(/\{clientId\}/, "Tudor").replace(/\{fieldId\}/, "search").replace(/\{versionId\}/, 1).replace(/\{filename}/, "hello.txt");
You can try this
String str = "/c1/client/{clientId}/field/{fieldId}/version/{versionId}/file/{filename}";
Map<String, String> map = new HashMap<String, String>();
map.put("clientId", "Tudor");
map.put("fieldId", "search");
map.put("versionId", "1");
map.put("filename", "hello.txt");
for (Map.Entry<String, String> entry : map.entrySet()) {
str = str.replace("{" + entry.getKey() + "}", entry.getValue());
}
String newStr = str.substring(1);
System.out.println(newStr);

How to Iterate Through Multiple Maps

So essentially, I have two hashmaps, one containing the following values:
rId33=image23
rId32=image22
rId37=image2
And the other containing this data:
{image2.jpeg=C:\Documents and Settings\image2.jpeg, image22.jpeg=C:\Documents and Settings\image22.jpeg, image23.jpeg=C:\Documents and Settings\image23.jpeg}
I basically want to be able to iterate through the first map, find a match of the key's, if a match is found, get the associated value, then look in the second map, find a match in the keys, then pull out the associated value (meaning the file path).
I was thinking of doing something like this for example (the follow is simplified)...
String val2 = "rId33";
for (String rID: map.keySet())
{
if (rID.contains(val2))
{
//enter code here
}
}
I was looking at the methods available for something like .getValue or something, but I'm not entirely sure how to do that. Any help would be appreciated. Thanks in advance for any replies.
Edited Code with Help From Bozho
else if ("v:imagedata".equals(qName) && headingCount > 0)
{
val2 = attributes.getValue("r:id");
String rID = imageMap.get(val2);
String path = imageLocation.get(rID + ".jpeg");
for (String rels: imageMap.keySet())
{
if (rels.contains(val2))
{
inImage = true;
image docImage = new image();
imageCount++;
docImage.setRelID(val2);
docImage.setPath(path);
addImage(docImage);
}
}
From what I see you don't need to iterate. Just:
String value1 = map1.get(key1);
if (value1 != null) {
String path = map2.get(value1 + ".jpeg");
}
If you don't always know whether it's value1 + ".jpeg", but you just know that the key starts with the first value, then you can iterate the 2nd map with:
for (Map.Entry<String, String> entry : map2.entrySet()) {
String key2 = entry.getKey();
String value2 = entry.getValue();
if (key.startsWith(value1)) {
return value2;
}
}
But note that the first code snippet is O(1) (both operations take constant time), while the 2nd is O(n)
And to answer the question as it is formulated in the title:
Get the iterators of both maps, and use it1.next() and it2.next() within a while loop. If any of the maps doesn't have more elements (it.hasNext()) - break.
That seems very inefficient. The entire point of a hash map is to do fast lookups. Do you really need to use that contains call on rID? In other words, can you change your hash map so that it directly contains the verbatim strings you want to search for and not just strings that contain the strings you want to search for as substrings? If yes, you could then use the answer given already. If not and if you must work with these data structures for whatever reason, the way to do what you're trying to do is something like:
String val2 = "rId33";
String path;
for (String rID: map.keySet())
{
if (rID.contains(val2))
{
path = secondMap.get(map.get(rID)+".jpeg");
break;
}
}
if (path == null)
{
//value not found
}

Categories