I am working on an application that churns output based on comparison of string input. I realize however that most modes of comparison are not applicable to strings. By these I am referring to:
less than(<)
less than and equal to(<=)
greater than(>)
greater than and equal to(>=)
equal to(==)
Is there a workaround that anyone might know about? I would appreciate any advice.
Thanks.
[RE-EDIT]
My application is a form that includes various fields. For instance when one enters a value in one textfield, that value is compared against a target value based on the conditions I listed above. And based on the result, execution can proceed.
I hope this sheds some light.
You can use String.compareTo(String) that returns an integer that's negative (<), zero(=) or positive(>).
Use it so:
String a="myWord";
if(a.compareTo(another_string) <0){
//a is strictly < to another_string
}
else if (a.compareTo(another_string) == 0){
//a equals to another_string
}
else{
// a is strictly > than another_string
}
What comparison do you need to do? The compareTo() method on String might do the trick.
If you have strings containing nummeric values you should try parsing them to a nummeric representation first. I.e.:
try {
long number1 = Long.parseLong(myString1);
long number2 = Long.parseLong(myString2);
if(number1 <= number2) {
// dosomething
}
} catch(NumberFormatException e) {
Log.e(TAG, "can not parse string to long",e);
}
for simple equals comparision there is the String.equals method:
if(myString1.equals(myString2)) {
// dosomething
Related
In the documentation of compareTo function, I read:
Returns zero if this object is equal to the specified other object, a
negative number if it's less than other, or a positive number if it's
greater than other.
What does this less than or greater than mean in the context of strings? Is -for example- Hello World less than a single character a?
val epicString = "Hello World"
println(epicString.compareTo("a")) //-25
Why -25 and not -10 or -1 (for example)?
Other examples:
val epicString = "Hello World"
println(epicString.compareTo("HelloWorld")) //-55
Is Hello World less than HelloWorld? Why?
Why it returns -55 and not -1, -2, -3, etc?
val epicString = "Hello World"
println(epicString.compareTo("Hello World")) //55
Is Hello World greater than Hello World? Why?
Why it returns 55 and not 1, 2, 3, etc?
I believe you're asking about the implementation of compareTo method for java.lang.String. Here is a source code for java 11:
public int compareTo(String anotherString) {
byte v1[] = value;
byte v2[] = anotherString.value;
if (coder() == anotherString.coder()) {
return isLatin1() ? StringLatin1.compareTo(v1, v2)
: StringUTF16.compareTo(v1, v2);
}
return isLatin1() ? StringLatin1.compareToUTF16(v1, v2)
: StringUTF16.compareToLatin1(v1, v2);
}
So we have a delegation to either StringLatin1 or StringUTF16 here, so we should look further:
Fortunately StringLatin1 and StringUTF16 have similar implementation when it comes to compare functionality:
Here is an implementation for StringLatin1 for example:
public static int compareTo(byte[] value, byte[] other) {
int len1 = value.length;
int len2 = other.length;
return compareTo(value, other, len1, len2);
}
public static int compareTo(byte[] value, byte[] other, int len1, int len2) {
int lim = Math.min(len1, len2);
for (int k = 0; k < lim; k++) {
if (value[k] != other[k]) {
return getChar(value, k) - getChar(other, k);
}
}
return len1 - len2;
}
As you see, it iterated over the characters of the shorter string and in case the charaters in the same index of two strings are different it returns the difference between them. If during the iterations it doesn't find any different (one string is prefix of another) it resorts to the comparison between the length of two strings.
In your case, there is a difference in the first iteration already...
So its the same as `"H".compareTo("a") --> -25".
The code of "H" is 72
The code of "a" is 97
So, 72 - 97 = -25
Short answer: The exact value doesn't have any meaning; only its sign does.
As the specification for compareTo() says, it returns a -ve number if the receiver is smaller than the other object, a +ve number if the receiver is larger, or 0 if the two are considered equal (for the purposes of this ordering).
The specification doesn't distinguish between different -ve numbers, nor between different +ve numbers — and so neither should you. Some classes always return -1, 0, and 1, while others return different numbers, but that's just an implementation detail — and implementations vary.
Let's look at a very simple hypothetical example:
class Length(val metres: Int) : Comparable<Length> {
override fun compareTo(other: Length)
= metres - other.metres
}
This class has a single numerical property, so we can use that property to compare them. One common way to do the comparison is simply to subtract the two lengths: that gives a number which is positive if the receiver is larger, negative if it's smaller, and zero of they're the same length — which is just what we need.
In this case, the value of compareTo() would happen to be the signed difference between the two lengths.
However, that method has a subtle bug: the subtraction could overflow, and give the wrong results if the difference is bigger than Int.MAX_VALUE. (Obviously, to hit that you'd need to be working with astronomical distances, both positive and negative — but that's not implausible. Rocket scientists write programs too!)
To fix it, you might change it to something like:
class Length(val metres: Int) : Comparable<Length> {
override fun compareTo(other: Length) = when {
metres > other.metres -> 1
metres < other.metres -> -1
else -> 0
}
}
That fixes the bug; it works for all possible lengths.
But notice that the actual return value has changed in most cases: now it only ever returns -1, 0, or 1, and no longer gives an indication of the actual difference in lengths.
If this was your class, then it would be safe to make this change because it still matches the specification. Anyone who just looked at the sign of the result would see no change (apart from the bug fix). Anyone using the exact value would find that their programs were now broken — but that's their own fault, because they shouldn't have been relying on that, because it was undocumented behaviour.
Exactly the same applies to the String class and its implementation. While it might be interesting to poke around inside it and look at how it's written, the code you write should never rely on that sort of detail. (It could change in a future version. Or someone could apply your code to another object which didn't behave the same way. Or you might want to expand your project to be cross-platform, and discover the hard way that the JavaScript implementation didn't behave exactly the same as the Java one.)
In the long run, life is much simpler if you don't assume anything more than the specification promises!
I have the following code to check if the value is Int or null and further check if it is below a certain number:
binding.RootLayout.forEach {
if (it is EditText) {
val intOrNull = it.text.toString().toIntOrNull()
if (intOrNull == null) {
count += 1
} else if (intOrNull > 100000) {
overTheLimitExist = true
}
}
}
The problem is, when I enter some number like 123456789 or below, it correctly identify it as (1) Int and (2) above the preset limit. However, if I enter a larger number such as 12345678900 it incorrectly identify it as null.
I search online for the toIntOrNull but they didn't say anything about a limit to the function.
12345678900 is larger than Integer's max value (2^31-1) , hence the implementation of toIntOrNull returns null, as 12345678900 doesn't fit in 4 bytes.
You can use toLongOrNull or toBigIntegerOrNull for really big numbers.
I think this problem is for limit of int type
(-2,147,483,648 to 2,147,483,647) you should use another type such as "Long" or BigNumber java class.
you can test 1 bigger than this range (2147483648) or 1 smaller (2147483646) and see the result.
I hope this help to you.
sorry for my English.
I understand that a precondition, in context of Desing by contract/Liskov principle, is something that should be true before the code is called, e.g. the caller is responsible for that. Also, the author of the Eiffel language stated that most people do put another verification check into the called cade, simply as means of defensive programming.
Some time ago I read a question with a code similar to this:
void X(int value)
{
if (value > 100)
{do something...}
}
Some commenters argued that the if statement is not a precondition but I do not think that is right - if the contract states V must be 100, then this is verifying the precondition additionally and if a class is derived from this type and changes to v > 200, it would be strenghtening the precondition and thus violating the Liskov principle. Or isn't that the case?
As you said, a precondition is defined as a condition that must always be true before the proceeding code executes.
This means that anything that checks for a condition at the beginning of a function before other code is executed, then it is considered a precondition.
Example:
//We will do something cool here
//With an integer input
int doSomethingCool(final int input)
{
//Wait, what if input is null or less than 100?
if(null == input || input < 100)
{
//Return a -1 to signify an issue
return -1;
}
//The cool bit of multiplying by 50. So cool.
final int results = input * 50;
//Return the results;
return results;
}
In the example, the function, input is checked before anything else is executed. So long as the conditions are met, then the rest of the code will execute.
Bad Example:
//We will do something cool here
//With an integer input
int doSomethingCool(final int input)
{
//Want to make sure input is not null and larger than 100
if(null != input && input > 100)
{
//The cool bit of multiplying by 50. So cool.
final int results = input * 50;
//Return the results;
return results;
}
//Return a -1 to signify an issue because the
//preconditions were not met for some reason
return -1;
}
In the example, the precondition is to check that input is not null and larger than 100. This is a bad precondition because it could introduce unnecessary nesting of ifs and loops.
Preconditions should do checks and only return when the checks fail. There should be no work done in a precondition.
In keeping with the Liskov Substitution Principle, if type S is a subtype of type T, then type T can be replaced with type S. If type S overrides doSomethingCool and changes the precondition, then it is in violation, because type T is the base definition and defines the intended conditions that must be met.
Now for your answer
Yes, simple conditions still count as preconditions. As long as they are at the front of all other code that uses the variable, the condition is as what is needed by the program. Also, if the function is in a subtype and is overriding the parent class, then it should not change the precondition.
However, do not surround the code that you need to run within the precondition. That is bad practice. If value needs to be larger than 100, check value < 100 and set a return in the if check.
First of all, I am aware of question 'Groovy String to int' and it's responses. I am a newbe to Groovy language and right now playing around some basics. The most straightforward ways to convert String to int seem to be:
int value = "99".toInteger()
or:
int value = Integer.parseInt("99")
These both work, but comments to these answers got me confused. The first methodString.toInteger() is deprecated, as stated in groovy documentation. I also assume that
Integer.parseInt() makes use of the core Java feature.
So my question is: is there any legal, pure groovy way to perform such a simple task as converting String to an int?
I might be wrong, but I think most Grooviest way would be using a safe cast "123" as int.
Really you have a lot of ways with slightly different behaviour, and all are correct.
"100" as Integer // can throw NumberFormatException
"100" as int // throws error when string is null. can throw NumberFormatException
"10".toInteger() // can throw NumberFormatException and NullPointerException
Integer.parseInt("10") // can throw NumberFormatException (for null too)
If you want to get null instead of exception, use recipe from answer you have linked.
def toIntOrNull = { it?.isInteger() ? it.toInteger() : null }
assert 100 == toIntOrNull("100")
assert null == toIntOrNull(null)
assert null == toIntOrNull("abcd")
If you want to convert a String which is a math expression, not just a single number, try groovy.lang.Script.evaluate(String expression):
print evaluate("1+1"); // note that evalute can throw CompilationFailedException
I suppose this:
public static string abc()
{
return "abc";
}
Is better to call this function in this way:
string call = abc();
Console.writeline(call);
Than this?
console.writeline(abc());
is there any reason to prefer one to the other?
Both are valid. However, out of experience I have concluded that the first option is more suitable for readability and ease of maintenance. I can't count how many times I have changed from the "compact" style to the first one as a help for a debugging session.
For example, this style makes it easy to check the correctness intermediate of an intermediate result:
string call = abc();
assert(!call.empty()); // Just an example.
Console.writeline(call);
Also, it helps to make the code more robust later, adding a conditional check before the subsequent action that checks call's value, for example if the design does not guarantee that the condition of the previous assert holds but you still need to check it.
string call = abc();
if (!call.empty())
{
Console.writeline(call);
}
Note also that with this style you will be able to easily inspect the value of call in your debugger.
Given your exact example (one parameter, value not used elsewhere, no side effects), it's just a matter of style. However, it gets more interesting if there are multiple parameters and the methods have side effects. For example:
int counter;
int Inc() { counter += 1; return counter }
void Foo(int a, int b) { Console.WriteLine(a + " " + b); }
void Bar()
{
Foo(Inc(), Inc());
}
What would you expect Foo to print here? Depending on the language there might not even be a predictable result. In this situation, assigning the values to a variable first should cause the compiler (depending on language) to evaluate the calls in a predictable order.
Actually I don't see a difference if you don't have any error checking.
This would make a difference
string call = abc();
# if call is not empty
{
Console.writeline(call);
}
The above method could avoid empty string being written.