Efficient way to perform various String operations - java

I have a Script in which i have to extract string from strings, get the last index, get nth character in a string, comparisons, string contains a string or not etc etc. I would like to know the best method/ practice to do such operations on strings in java. Should i use StringBuilder all the time to perform the above operations. In few cases i have used regular expressions to find strings.
So what should i use?
Scenario is : loads of comparisons and indexes have to found. Thanks.!
example :
String name = "application/octet-stream; name=\"2012-04-20.tar.gz\""; // get 2012-04-20.tar.gz
Pattern pattern = Pattern.compile("\"(.*?)\"");
Matcher matcher = pattern.matcher(name);
if (matcher.find()) {
System.out.println(matcher.group(1));
}
String date = " Number 4, December 2013";
String year = date.substring(date.lastIndexOf(" ")+1);
String month = date.substring(date.indexOf(',')+2,date.indexOf(" ",date.indexOf(',')+2 ));
date = year+getMonth(month)+"01";
System.out.println(date);
Like above, many other extraction of string within string.

When you deal with large amount of String object use String intern function wisely to conserve heap space and eliminate object creation overhead. refer here for more information

Since you are not manipulating the strings, you can use String or StringUtils instead of StringBuilder

All of these operations can be done with the String class, see below for the methods you should use.
extract string from strings
String.substring()
get the last index
String.length() -1
the last character
s.charAt(s.length()-1);
get nth character in a string
String.charAt()
comparisons
String.compareTo()
string contains a string or not
String.contains()
You can also use String.toLowerCase() on both if necessary

Related

How to find a String of last 2 items in colon separated string

I have a string = ab:cd:ef:gh. On this input, I want to return the string ef:gh (third colon intact).
The string apple:orange:cat:dog should return cat:dog (there's always 4 items and 3 colons).
I could have a loop that counts colons and makes a string of characters after the second colon, but I was wondering if there exists some easier way to solve it.
You can use the split() method for your string.
String example = "ab:cd:ef:gh";
String[] parts = example.split(":");
System.out.println(parts[parts.length-2] + ":" + parts[parts.length-1]);
String example = "ab:cd:ef:gh";
String[] parts = example.split(":",3); // create at most 3 Array entries
System.out.println(parts[2]);
The split function might be what you're looking for here. Use the colon, like in the documentation as your delimiter. You can then obtain the last two indexes, like in an array.
Yes, there is easier way.
First, is by using method split from String class:
String txt= "ab:cd:ef:gh";
String[] arr = example.split(":");
System.out.println(arr[arr.length-2] + " " + arr[arr.length-1]);
and the second, is to use Matcher class.
Use overloaded version of lastIndexOf(), which takes the starting index as 2nd parameter:
str.substring(a.lastIndexOf(":", a.lastIndexOf(":") - 1) + 1)
Another solution would be using a Pattern to match your input, something like [^:]+:[^:]+$. Using a pattern would probably be easier to maintain as you can easily change it to handle for example other separators, without changing the rest of the method.
Using a pattern is also likely be more efficient than String.split() as the latter is also converting its parameter to a Pattern internally, but it does more than what you actually need.
This would give something like this:
String example = "ab:cd:ef:gh";
Pattern regex = Pattern.compile("[^:]+:[^:]+$");
final Matcher matcher = regex.matcher(example);
if (matcher.find()) {
// extract the matching group, which is what we are looking for
System.out.println(matcher.group()); // prints ef:gh
} else {
// handle invalid input
System.out.println("no match");
}
Note that you would typically extract regex as a reusable constant to avoid compiling the pattern every time. Using a constant would also make the pattern easier to change without looking at the actual code.

Get specific value from string using split fucntion

I have String something like this
APIKey testapikey=mysecretkey
I want to get mysecretkey to String attribute
What i tried is below
String[] couple = string.split(" ");
String[] values=couple[1].split("=");
String mykey= values[1];
Is this right way?
You could use the String.replaceAll(...) method.
String string = "APIKey testapikey=mysecretkey";
// [.*key=] - match the substring ending with "key="
// [(.*)] - match everything after the "key=" and group the matched characters
// [$1] - replace the matched string by the value of cpaturing group number 1
string = string.replaceAll(".*key=(.*)", "$1");
System.out.println(string);
Don't use split() you will be unnecessarily creating an array of Strings.
Use String myString = originalString.replaceAll(".*=","");
I think using split here is pretty error prone. A small change in the format of the incoming string (such as a space being added) could result in a bug that's hard to diagnose. My recommendation would be to play it safe and use a regular expression to ensure the text is exactly as you expect:
Pattern pattern = Pattern.compile("APIKey testapikey=(\\w*)");
Matcher matcher = pattern.matcher(apiKeyText);
if (!matcher.matches())
throw new IllegalArgumentException("apiKey does not match pattern");
String apiKey = matcher.group();
That code documents your intentions much better than use of split and picks up unexpected changes in format. The only possible downside is performance but assuming you make pattern a static final (to ensure it's compiled once) then unless you are calling this millions of times then I very much doubt it will be an issue.

match all characters in a string independent of their order in the sequence

I want to match certain group of characters in a String independent of their order in the String using regex fucntion. However, the only requirement is that they all must be there.
I have tried
String elD = "15672";
String t = "12";
if ((elD.matches(".*[" + t + "].*"))) {
System.out.println(elD);
}
This one checks whether any of the characters are present. But I want all of them to be there.
Also I tried
String elD = "15672";
String t = "12";
if ((elD.matches(".*(" + t + ").*"))) {
System.out.println(elD);
}
This does not work as well. I have searched quite a while but I could not find an example when all of the characters from the pattern must be present in the String independent of their order.
Thanks
You can write regex for this but it would not look nice. If you would want to check if your string contains anywhere x and y you would need to use few times look-ahead like
^(?=.*x)(?=.*y).*$
and use it like
yourStirng.matches(regex);
But this way you would need to create your own method which would generate you dynamic regex and add (?=.*X) for each character you want to check. You would also need to make sure that this character is not special in regex like ? or +.
Simpler and not less effective solution would be creating your own method which would check if your string contains all searched characters, something like
public static boolean containsUnordered(String input, String searchFor){
char[] characters = searchFor.toCharArray();
for (char c: characters)
if (!input.contains(String.valueOf(c)))
return false;
return true;
}
You can built a pattern from the search string using the replaceAll method:
String s = "12";
String pattern = s.replaceAll("(.)", "(?=[^$1]*$1)");
Note: You can't test the same character several times. (i.e. 112 gives (?=[^1]*1)(?=[^1]*1)(?=[^2]*2) that is exactly the same as (?=[^1]*1)(?=[^2]*2))
But in my opinion Pshemo method is probably more efficient.

Dealing with different String date formats

In java, I have a string with a date in dd-mm-yyyy format:
String value = "31-01-1989";
Now, I want the value in another variable to be ddmmyyyy format:
String value = "31011989";
How to do this?
In this case you can simply remove dashes
value = value.replace("-", "");
or
value = value.replaceAll("-", "");
but according to my tests the first version is a little bit faster. So I personally prefer to use replaceAll only when the first parameter is a regex.
Note that, despite a confusion in the names, String.replace replaces ALL substrings that match the first arg, just as String.replaceAll does. The main difference is that the String.replace treats the first arg as a string literal and String.replaceAll uses it as a regex.
easy solution:
String value1 = "31-01-1989";
String value2 = value1.replace("-", "");
Have a look at SimpleDateFormat for a general solution. Write a SimpleDateFormat to parse the first date and use format in another to have the expected output.
You can use String.replace(Charseq, Charseq) to remove the delimiters.
String value = "31-01-1989";
String value2 = value.replace("-", "");
System.out.println(value2);

Regarding extracting a string

I have a string Till No. S59997-RSS01 Now I need to extract the 01 from it , but the issue is that it is dynameic means
String TillNo =pinpadTillStore.getHwIdentifier();
The value S59997-RSS01 is in TillNo, that I come to know from debugging but in real time which value is coming inside TillNo , will not be known to me but the pattern of the value will be the same (S59997-RSS01) , Please advise how to extract the last two digits like(01)
int size = tillNo.length();
String value = tillNo.substring(size-2); // do this if size > 2.
You can use the subString method.
Refer to how to use subString()
If the two digits will only appear at last two position, just use the substring method. For a more flexible way, use Regular Expression instead.
String TillNo = "S59997-RSS01";
System.out.println(TillNo.substring(TillNo.length() - 2));
Pattern pattern = Pattern.compile("S[\\d]{5}-RSS([\\d]{2})");
Matcher matcher = pattern.matcher(TillNo);
if (matcher.find()) {
System.out.println(matcher.group(1));
}
exactly, you can extract the last 2 digits using the substring method for strings like:
String TillNo="S59997-RSS01";
String substring=TillNo.substring(TillNo.length()-2,TillNo.length());

Categories

Resources