String CompanyData = "{ChargeCompany1Cnt:0,ChargeCompany2Cnt:73,ChargeCompany3Cnt:44,BalanceCompany3Cnt:0,ChargeCompany4Flag:green,BalanceCompany2Flag:green,BalanceCompany1Cnt:0,ChargeCompany3Flag:red,ChargeCompany1Flag:green,BalanceCompany4Flag:green,BalanceCompany1Flag:green,BalanceCompany2Cnt:0,BalanceCompany4Cnt:0,BalanceCompany3Flag:green,ChargeCompany2Flag:red,ChargeCompany4Cnt:6}";
CompanyData is my string I am splitting the data like below. There is no issue with this code, but if the order is changed in the string splitting is breaking.
how to split this string and assign to another string by its name(like splitting based on ChargeCompany1Cnt, ChargeCompany2Cnt). i have used cut and sed commands in UNIX to do this, right now converting my Shell script into JAVA. So sorry if it's a basic question
String ChargeCompany1Cnt=CompanyData.split(,)[0].replace("{","");
String ChargeCompany2Cnt=CompanyData.split(,)[1];
String ChargeCompany3Cnt=CompanyData.split(,)[2];
String BalanceCompany3Cnt=CompanyData.split(,)[3];
String ChargeCompany1Flag=CompanyData.split(,)[8];
Basically I need to find String like ChargeCompany2Cnt,ChargeCompany1Flag in CompanyData and print ChargeCompany2Cnt:73 ChargeCompany1Flag:green
Please note if this is JSON object you can parse it easily with ObjectMapper
of Jacson. you can use the below code for manual parsing
String CompanyData = "{ChargeCompany1Cnt:0,ChargeCompany2Cnt:73,ChargeCompany3Cnt:44,BalanceCompany3Cnt:0,ChargeCompany4Flag:green,BalanceCompany2Flag:green,BalanceCompany1Cnt:0,ChargeCompany3Flag:red,ChargeCompany1Flag:green,BalanceCompany4Flag:green,BalanceCompany1Flag:green,BalanceCompany2Cnt:0,BalanceCompany4Cnt:0,BalanceCompany3Flag:green,ChargeCompany2Flag:red,ChargeCompany4Cnt:6}";
HashMap<String,String> mymap = new HashMap<String,String>();
for ( String s: CompanyData.split("[?,{}]")) {
if (!s.equals(""))
mymap.put(s.split(":")[0],s.split(":")[1]); }
for (HashMap.Entry<String, String> entry : mymap.entrySet()) {
String key = entry.getKey().toString();;
String value = entry.getValue();
System.out.println( key + " = " + value );
Your question isn't too clear, but perhaps this snippet will point you in the right direction:
List<String> companyCount = new ArrayList<>();
String[] companies = CompanyData.substring(1, -1).split(",");
for (String companyCnt : companies) {
companyCount.add(companyCnt);
}
Incidentally, you can probably perform this whole operation without use of cut(1) as well.
Depending on how you intend to use the variables you could alternatively create a set of key-value pairs instead of explicitly declaring each variable.
Then you could split the names out (i.e. split each element further on :) and use them as keys without needing to know which is which.
Related
I have a condition like :
public String createId(List<String> list)
{
String id="";
if(list.contains("name"))
id+="TEST VALUE NAME";
if(list.contains("age"))
id+="Test Value AGE";
.
.
. likewise many if condition
return id;
}
As per my understanding we should use StringBuilder in loop condition and String in simple concatenation. So here wanted to ask I should use String or StringBuilder? Kindly suggest
StringBuilder is the best for this scenario because it's mutable. the String is immutable so when you modify the string it creates a new object.
It seems that for the given task it would be better to get rid of the multiple duplicated if statements by defining a list of the keys to match the input list and use Stream API to generate the string id, e.g. Collectors.joining with delimiter or without the delimiter.
Assuming that there is a single rule to create a part of the id: append "Test Value " + key.toUpperCase(), the implementation may look as follows:
final List<String> keys = Arrays.asList(
"name", "age" /* and other needed keys*/
);
public String createId(List<String> list) {
return keys
.stream()
.filter(list::contains)
.map(String::toUpperCase)
.map(str -> "Test Value " + str)
.collect(Collectors.joining("_")); // or Collectors.joining()
}
System.out.println(createId(Arrays.asList("age", "name", "surname")));
// output: Test Value NAME_Test Value AGE
If custom parts should be provided for name, age, etc., a Map of matches should be prepared and used, also it may make sense to convert the input list into Set<String to facilitate look-ups:
final Map<String, String> keys = new LinkedHashMap<>(); {
// fill the map in special order
keys.put("name", "Name Part");
keys.put("age", "Test Age");
/* and other needed keys*/
}
public String createId(List<String> list) {
Set<String> words = new HashSet<>(list);
return keys.keySet()
.stream()
.filter(words::contains) // faster lookup O(1) at the cost of another collection
.map(keys::get)
.collect(Collectors.joining("_")); // or Collectors.joining()
}
System.out.println(createId(Arrays.asList("age", "surname", "name")));
// output: Name Part_Test Age
In general your understanding is correct about when to use String concatenation vs StringBuilder. The Java Language Specification says
To increase the performance of repeated string concatenation, a Java
compiler may use the StringBuffer class or a similar technique to
reduce the number of intermediate String objects that are created by
evaluation of an expression.
For the larger majority of cases you should use whichever method results in better readability and maintainability.
I have a method with return type as string below is the string which is getting retrieved how should in convert this string to setso that i can iterate through the String set.
["date:#value2","lineofbusiness:#value3","pnrno:#value1","reason:#value4"]
If i try to split using String[] the result is not expected i have to get these individual values like date:#value2 and have to split this to complete the rest of my logic.
How to convert the above string to below string set
Set<String> columnmapping = new HashSet<String>();
I use Apache Commons for string manipulation. Following code helps.
String substringBetween = StringUtils.substringBetween(str, "[", "]").replaceAll("\"", ""); // get rid of bracket and quotes
String[] csv = StringUtils.split(substringBetween,","); // split by comma
Set<String> columnmapping = new HashSet<String>(Arrays.asList(csv));
In addition to the accepted answer there are many options to make it in "a single line" with standards Java Streams (assuming Java >= 8) and without any external dependencies, for example:
String s =
"[\"date:#value2\",\"lineofbusiness:#value3\",\"pnrno:#value1\",\"reason:#value4\"]";
Set<String> strings = Arrays.asList(s.split(",")).stream()
.map(s -> s.replaceAll("[\\[\\]]", ""))
.collect(Collectors.toSet());
When someone get rest method called by using below url hit the controllerMethod.
For example URL string like:
String queryurl=http://localhost:8081/servcie/details?id=101&type=124;
String changedQueryUrl=null;
#GetMapping(value = "details")
public MyModel controllerMethod(#RequestParam Map<String, String> customQuery,HttpServletRequest request) {
//i have to replace words "id" with rollNo and "type" with datatype
// so that i have done below sample code
for ( Entry<String, String> entry : customQuery.entrySet()) {
if (entry.getKey().equals("id")) {
changedQueryUrl= request.getQueryString().replaceAll("\\bid\\b", "rollNo");
}
else if (entry.getKey().equals("type")) {
changedQueryUrl= request.getQueryString().replaceAll("\\btype\\b", "datatype");
}
}
}
when i am printing changedQueryUrl only one of word is replacing other word is not replacing.
I want to print the output like with exact matching words
changedQueryUrl=http://localhost:8081/servcie/details?rollNo=101&datatype=124
replaceAll returns a new copy of the original string, so the first replace don't change the original String request.queryString(). The second replaceAll works on request.queryString() which has no effect because you need to work with the result of replaceAll.
And don't use request.queryString() anymore in your loop, if you want to make your code working you can assign changedQueryUrl= request.getQueryString(); before the loop and use changedQueryUrl.replaceAll(...) instead of request.getQueryString().replaceAll(...).
Or just do
String queryurl = "http://localhost:8081/servcie/details?id=101&type=124;";
String queryRes = queryurl.replaceAll("\\bid\\b", "rollNo").replaceAll("\\btype\\b", "datatype");
I need to parse a formula and get all the variables that were used. The list of variables is available. For example, the formula looks like this:
String f = "(Min(trees, round(Apples1+Pears1,1)==1&&universe==big)*number";
I know that possible variables are:
String[] vars = {"trees","rivers","Apples1","Pears1","Apricots2","universe","galaxy","big","number"};
I need to get the following array:
String[] varsInF = {"trees", "Apples1","Pears1", "universe", "big","number"};
I believe that split method is good here but can’t figure the regexp required for this.
No need for any regex pattern - just check which item of the supported vars is contained in the given string:
List<String> varsInf = new ArrayList<>();
for(String var : vars)
if(f.contains(var))
varsInf.add(var);
Using Stream<> you can:
String[] varsInf = Arrays.stream(vars).filter(f::contains).toArray(String[]::new);
Assuming "variable" is represented by one alphanumeric character or sequential sequence of multiple such characters, you should split by not-alphanumeric characters, i. e. [^\w]+, then collect result by iteration or filter:
Set<String> varSet = new HashSet<>(Arrays.asList(vars));
List<String> result = new ArrayList<>();
for (String s : f.split("[^\\w]+")) {
if (varSet.contains(s)) {
result.add(s);
}
}
I want to read data from a .epf file, and the data is like:
/instance/org.eclipse.wb.core/design.palette.flyout.width=192
I think I can use Map<String, String> to store it, but the problem is how to get rid of the =, and then put the left part and right part into the Map?
As jarnbjo mentioned, if it conforms to the property file format, you can read the file using the Properties class.
If you want to store the data in a map, you can use a string function to get the 2 parts of the data:
// Assuming data contains "/instance/org.eclipse.wb.core/design.palette.flyout.width=192"
String[] parts = data.split("=");
// Get the parts
String key = parts[0]; // /instance/org.eclipse.wb.core/design.palette.flyout.width
String value = parts[1]; // 192
// Or just directly use the map
map.put(parts[0], parts[1]);
To test beforehand if the string contains an, just use String#contains().
if (string.contains("=")) {
// Split it.
} else {
throw new IllegalArgumentException("String " + string + " does not contain =");
}
If the files conform to the property file format, you can read them using the Properties class.