I tried:
String test = "racecary";
StringBuilder stringBuilder = new StringBuilder(test);
System.out.println(stringBuilder.reverse()+" -------------");
if (stringBuilder.reverse().toString().equalsIgnoreCase(test)) {
System.out.println("Pass");
}else {
System.out.println("Fail");
}
It always prints pass, even when I mispelled racecar, but passes when I use == inplace of .equalsIgnoreCase.
Am I doing something wrong?
I have already gone through following but didnt get the answer.
JAVA .equalsIgnoreCase not working
JAVA .equalsIgnoreCase not working
StringBuilder.reverse() modifies the builder in place. The test printout is causing the string to be reversed twice, leaving it unmodified. Get rid of the printout and the code will work as expected.
Related
I know this is going to end up with me smacking my head but I don't understand why this does not worked as expected. Basically I am calling a google Sheet Append method getting the result and saving the last row value.
I have tried these and still the toIntOrNull ends up null but if I use a numeric value (s ="117" it works as expected ! So at this point I'm totally stumped. Using the Android Studio scratch utility
/*This should produce the output of an Integer !
response from Google Sheets Append
"updatedRange":"tData!A117:I117","updatedRows":1}}
get the "target"
var s: String = result.updates.updatedRange.substringAfter("I")
this returns "117" as expected
testing ! */
var s = "tData!A117:I117"
s = s.substringAfter("I")
// again result is 117 with a length of 3
// .trimStart("I"
var lr = s.toIntOrNull()
println ("$s $lr") // 117 null Why ?
I'm very new to groovy (here working on Jenkinsfile)
One of my coworkers uses a Match Operator to check a condition. But I find it not readable and hard to maintain.
Original Match Operator:
PROJECT_NAME = 'projectA' // User Input from Jenkins params normaly
if ( "${PROJECT_NAME}" ==~ /projectA|projectB|projectC|projectD/) { // The real line is 300 Char long
// Do stuff
}
There is 15 projects in total, i've shorten up the line because it was too long. So every time he needs to add a project name, he appends at the start or end of his regex.
Also, those project name are in a list before.
projects = ['projectA',
'projectB',
'projectC',
'projectD']
Could there be a way to use this list to build the regex?
Here is what I tried:
string_regex = "/"
for (project in projects) {
string_regex = string_regex + project + "|"
}
string_regex = string_regex.substring(0, string_regex.length() - 1)
string_regex = string_regex + "/"
print "${string_regex}\n"
if ("${PROJECT_NAME}" ==~ string_regex) {
print "Well Done you did it\n"
// Do stuff
}
But saddly it doesn't seems to work, since I'm using a string?
EDIT: I found out that I could use the contains method from a list in Groovy. In my case, it fixes my original problem. But I'm still curious on how to build such regex with strings.
if (projects.contains(PROJECT_NAME)) {
// Do stuff
}
You can join your projects and then turn the string into a regexp via Pattern.compile(). For good measure use Pattern.quote() to safe-guard against chars in your project names with "meaning" in regexp.
import java.util.regex.Pattern
def projects = ['projectA',
'projectB',
'projectC',
'projectD']
def re = Pattern.compile(projects.collect{ Pattern.quote it }.join("|"))
['projectA', 'projectX'].each{
println it ==~ re
}
// -> true
// -> false
For what it's worth, I came to like the Groovy matching operators for their compact syntax. If you learn about them and practice for a short bit, you will probably get to like them, too.
Regardless, for a simple check, on whether a String is part of a list, there is a much simpler way in Groovy than using full blown regexp : the in operator, e.g.:
def projects = ['projectA',
'projectB',
'projectC',
'projectD']
['projectA', 'projectX'].each {
println "${it} is ${it in projects ? 'IN' : 'NOT IN'} the project list"
}
which yields e.g.:
projectA is IN the project list
projectX is NOT IN the project list
More info on that operator and many other aspects of the Groovy language from the always excellent MrHaki here
Of course, if you need to account for case differences, etc... you have to massage the code a bit, but at some point, a regexp might be warranted.
If you have already an collection, you should nearly always use an collection operator; E.g. replace
if ( "${PROJECT_NAME}" ==~ /projectA|projectB|projectC|projectD/) {
with:
if (PROJECT_NAME in projects) {
Much easier to read and understand, no? 😉
I got some function:
private fun selectHometown() = File("data/towns.txt")
.readText()
.split("\n")
.shuffled()
.first()
And if I try to get or print some string with the 2 values obtained from this function, the first value disappears. For example:
println("${selectHometown() ${selectHometown() }")
Will only print one city name, while I expect two. I guess the problem is related to string concatenation in Kotlin. Of course, I can get the desired result in a different way, but I'm wondering why this one doesn't work.
Windows way of terminating a line is to use "\r\n" so use it as delimiter :
private fun selectHometown() = File("data/towns.txt")
.readText()
.split("\r\n")
.shuffled()
.first()
println("${selectHometown()} ${selectHometown()}")
String header = "EXL=TST+​[Placeholder1]​+[Placeholder2]+[Placeholder3]​:[Placeholder2]​"
header = header.replaceAll("\\[Placeholder1\\]", escapeEdi((String)${propertyVal1}))
header = header.replaceAll("\\[Placeholder2\\]", escapeEdi((String)${propertyVal2}))
header = header.replaceAll("\\[Placeholder3\\]", escapeEdi((String)${propertyVal3}))
println(header)
String escapeEdi(String target){
StringBuilder result = new StringBuilder();
for(char c : target.toCharArray()){
switch(c){
case '+':
case ':':
case '\'':
case '?':
result.append("?");
default:
result.append(c);
}
}
return result.toString();
}
With the above sample code, I'm getting the payload result with a lot of question marks within it:
Example payload:
EXL=TST+​1+?1234?+1234+123?:123?+?1-1-170101?++?TEST?'
Even removing the escapeEdi function nets the exact same result. I'm not even sure if the escape edi is needed, and frankly none of the values passed have any such characters, purely alphanumeric.
Because of the ?, it's causing the message to be sent with a UTF-8-BOM, and their end is just not designed to handle it, which means it must be cleared and removed on my end. How can I get rid of all these ?
A simple replaceAll with an empty string didn't work.
Trying to escapeEdi() at the end of the result didn't do anything either, and I have a very similar script to this which works just fine, no silly character included. What might be causing this issue?
the funny thing )
the following code
String header = "EXL=TST+​[Placeholder1]​+xxx"
header = header.replaceAll("\\[Placeholder1\\]", "val1")
println header
produces
EXL=TST+?val1?+xxx
and finally i found that there is a strange spaces before and after [] in your source string with uni-code value (8203)
and it is Unicode Character 'ZERO WIDTH SPACE' (U+200B)
see on the screenshot in green:
I am working in a groovy/grails set up and am having some trouble trying to execute a switch statement on a String value.
Basically, I am looping through the attribute names in a webservice response to see if they match pre-defined mappings that are configured on a per user basis. If they have established a mapping on that field, I pull the value out of the response and use it elsewhere.
The code looks something like this:
switch(attributeName)
{
case {attributeName} :
log.info("Currently switching on value... ${attributeName}")
case user.getFirstNameMapping():
model.user.userInfo.firstName = attributeValue
break
case user.getLastNameMapping():
model.user.userInfo.lastName = attributeValue
break
case user.getAuthenticationKeyMapping():
model.authenticationValue = attributeValue
break
case user.getEmailMapping():
model.email = attributeValue.toLowerCase()
break
}
The value being switched on (attributeName) is of type String, and the getter methods for the user instance also return type String.
Based on my research and understanding of the Groovy language, switching on an Object such as a String should end up using String.equals() to make the comparison. The result, however, is that it is matching on the user.getFirstNameMapping() case every time, and repeatedly overwriting the value in the model; therefore, the last value that comes back in the response is what ends up saved, and none of the other values are saved.
What's interesting is that if I use an if/else structure and do something like this:
if(attributeName.equals(user.getFirstNameMapping())
{
...
}
It works fine every time. I've verified through logging that it's not something silly like extra whitespace or a capitalization issue. I've also tried changing things around to run the switch by default and explicitly compare the attributeName in the case like this:
switch(true)
{
case {attributeName} :
log.info("Currently switching on value... ${attributeName}")
case {user.getFirstNameMapping().equals(attributeName)}:
model.user.userInfo.firstName = attributeValue
break
case {user.getLastNameMapping().equals(attributeName)}:
model.user.userInfo.lastName = attributeValue
break
case {user.getAuthenticationKeyMapping().equals(attributeName)}:
model.authenticationValue = attributeValue
break
case {user.getEmailMapping().equals(attributeName)}:
model.email = attributeValue.toLowerCase()
break
}
And it still fails to meet my expectations in the exact same way. So, I'm wondering why this is the behavior when the switch statement should simply be using .equals() to compare the strings, and when I explicitly compare them in an if/else using .equals(), it works as expected.
The issue is in your switch case.
Have a look here :-
case {attributeName} :
log.info("Currently switching on value... ${attributeName}")
case user.getFirstNameMapping():
model.user.userInfo.firstName = attributeValue
break
As you can see your these two cases will run every time because the switch condition is :-
switch(attributeName)
So the first one will get match and will run until it encounters break; which is at after case 2 i.e. case user.getFirstNameMapping(): so i would suggest you to print the value of {attributeName} before the swtich starts.
Hope that will help you.
Thanks
I don't know exactly what's your issue, but the case statement works just fine, even with methods. See my example
String something = "Foo"
class User {
String firstName
String lastName
}
User u = new User(firstName: 'Something', lastName:'Foo')
switch(something) {
case u.getFirstName():
println "firstName: ${u.firstName}"
break;
case u.getLastName():
println "lastName: ${u.lastName}"
break;
default:
println "nothing..."
}
This code will print lastName as expected.
​