num == Integer.parseInt(str) is going to faster than str.equals("" + num)
str.equals("" + num) will first convert num to string which is O(n) where n being the number of digits in the number. Then it will do a string concatenation again O(n) and then finally do the string comparison. String comparison in this case will be another O(n) - n being the number of digits in the number. So in all ~3*O(n)
num == Integer.parseInt(str) will convert the string to integer which is O(n) again where n being the number of digits in the number. And then integer comparison is O(1). So just ~1*O(n)
To summarize both are O(n) - but str.equals("" + num) has a higher constant and so is slower.
num == Integer.parseInt(str) is going to faster than str.equals("" + num)
str.equals("" + num) will first convert num to string which is O(n) where n being the number of digits in the number. Then it will do a string concatenation again O(n) and then finally do the string comparison. String comparison in this case will be another O(n) - n being the number of digits in the number. So in all ~3*O(n)
num == Integer.parseInt(str) will convert the string to integer which is O(n) again where n being the number of digits in the number. And then integer comparison is O(1). So just ~1*O(n)
To summarize both are O(n) - but str.equals("" + num) has a higher constant and so is slower.
I think num == Integer.parseInt(str) is a better way of doing comparison. Because str.equals("" + num) this is not the ideal way how you should compare integer values and also it will create unnecessary String constant objects in the String pool (which hampers performance).
Videos
To convert to an integer, use Integer.valueOf(String):
if (Integer.valueOf(buf) == 1) {
A better option is to use the method from JOptionPane that asks for input with given selections. This way you would force the user to input 1, 2 or 3, and at the same there would be no need to convert to an integer.
Integer result = (Integer) JOptionPane.showInputDialog(null, "1, 2 or 3", "title", JOptionPane.QUESTION_MESSAGE, null, new Integer[]{1,2,3}, 1);
if (result == 1) {
...
} else if (result == 2) {
...
} else if (result == 3) {
...
}
int value = Integer.parseInt(buff);
if(value == 1){...}
else if(value == 2){...}
else if(value == 3){...}
/**
* Similar to compareTo method But compareTo doesn't return correct result for string+integer strings something like `A11` and `A9`
*/
private int newCompareTo(String comp1, String comp2) {
// If any value has 0 length it means other value is bigger
if (comp1.length() == 0) {
if (comp2.length() == 0) {
return 0;
}
return -1;
} else if (comp2.length() == 0) {
return 1;
}
// Check if first string is digit
if (TextUtils.isDigitsOnly(comp1)) {
int val1 = Integer.parseInt(comp1);
// Check if second string is digit
if (TextUtils.isDigitsOnly(comp2)) { // If both strings are digits then we only need to use Integer compare method
int val2 = Integer.parseInt(comp2);
return Integer.compare(val1, val2);
} else { // If only first string is digit we only need to use String compareTo method
return comp1.compareTo(comp2);
}
} else { // If both strings are not digits
int minVal = Math.min(comp1.length(), comp2.length()), sameCount = 0;
// Loop through two strings and check how many strings are same
for (int i = 0;i < minVal;i++) {
char leftVal = comp1.charAt(i), rightVal = comp2.charAt(i);
if (leftVal == rightVal) {
sameCount++;
} else {
break;
}
}
if (sameCount == 0) {
// If there's no same letter, then use String compareTo method
return comp1.compareTo(comp2);
} else {
// slice same string from both strings
String newStr1 = comp1.substring(sameCount), newStr2 = comp2.substring(sameCount);
if (TextUtils.isDigitsOnly(newStr1) && TextUtils.isDigitsOnly(newStr2)) { // If both sliced strings are digits then use Integer compare method
return Integer.compare(Integer.parseInt(newStr1), Integer.parseInt(newStr2));
} else { // If not, use String compareTo method
return comp1.compareTo(comp2);
}
}
}
}
public static String extractNumber(final String str) {
if(str == null || str.isEmpty()) return "";
StringBuilder sb = new StringBuilder();
boolean found = false;
for(char c : str.toCharArray()){
if(Character.isDigit(c)){
sb.append(c);
found = true;
} else if(found){
// If we already found a digit before and this char is not a digit, stop looping
break;
}
}
return sb.toString();
}
For input "123abc", the method above will return 123.
For "abc1000def", 1000.
For "555abc45", 555.
For "abc", will return an empty string.
// Then you can parse that to integer and then compare
== tests for reference equality (whether they are the same object).
.equals() tests for value equality (whether they contain the same data).
Objects.equals() checks for null before calling .equals() so you don't have to (available as of JDK7, also available in Guava).
Consequently, if you want to test whether two strings have the same value you will probably want to use Objects.equals().
// These two have the same value
new String("test").equals("test") // --> true
// ... but they are not the same object
new String("test") == "test" // --> false
// ... neither are these
new String("test") == new String("test") // --> false
// ... but these are because literals are interned by
// the compiler and thus refer to the same object
"test" == "test" // --> true
// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true
// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true
From the Java Language Specification JLS 15.21.3. Reference Equality Operators == and !=:
While
==may be used to compare references of typeString, such an equality test determines whether or not the two operands refer to the sameStringobject. The result isfalseif the operands are distinctStringobjects, even if they contain the same sequence of characters (§3.10.5, §3.10.6). The contents of two stringssandtcan be tested for equality by the method invocations.equals(t).
You almost always want to use Objects.equals(). In the rare situation where you know you're dealing with interned strings, you can use ==.
From JLS 3.10.5. String Literals:
Moreover, a string literal always refers to the same instance of class
String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the methodString.intern.
Similar examples can also be found in JLS 3.10.5-1.
Other Methods To Consider
String.equalsIgnoreCase() value equality that ignores case. Beware, however, that this method can have unexpected results in various locale-related cases, see this question.
String.contentEquals() compares the content of the String with the content of any CharSequence (available since Java 1.5). Saves you from having to turn your StringBuffer, etc into a String before doing the equality comparison, but leaves the null checking to you.
== tests object references, .equals() tests the string values.
Sometimes it looks as if == compares values, because Java does some behind-the-scenes stuff to make sure identical in-line strings are actually the same object.
For example:
String fooString1 = new String("foo");
String fooString2 = new String("foo");
// Evaluates to false
fooString1 == fooString2;
// Evaluates to true
fooString1.equals(fooString2);
// Evaluates to true, because Java uses the same object
"bar" == "bar";
But beware of nulls!
== handles null strings fine, but calling .equals() from a null string will cause an exception:
String nullString1 = null;
String nullString2 = null;
// Evaluates to true
System.out.print(nullString1 == nullString2);
// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));
So if you know that fooString1 may be null, tell the reader that by writing
System.out.print(fooString1 != null && fooString1.equals("bar"));
The following are shorter, but it’s less obvious that it checks for null:
System.out.print("bar".equals(fooString1)); // "bar" is never null
System.out.print(Objects.equals(fooString1, "bar")); // Java 7 required
An Integer will never be equal to a String.
Both classes have very strict equals() definitions that only accept objects of their respective types.
Integer.equals():The result is true if and only if the argument is not
nulland is anIntegerobject that contains the same int value as this object.String.equals():The result is true if and only if the argument is not
nulland is aStringobject that represents the same sequence of characters as this object.
That's actually a quite common way to implement equals(): only objects of the same class (and occasionally subclasses) can be equal. Other implementations are possible, but are the exception.
One common exception are the collections such as List: every List implementation that follows the convention will return true when compared to any other implementation, if it has the same content in the same order.
Usually, when implementing equals(), one of the first things to do is to check whether the objects are of one and the same type.
public boolean equals(Object obj) {
if (!(obj instanceof SomeType)) return false;
...
}
This is also applied in the Integer and String classes, which answers the question why do you receive false as a result.
Integer.parseInt("4") == Integer.parseInt("04")
That is it. You can convert a numeric string into integer using Integer.parseInt(String) method, which returns an int type. And then comparison is same as 4 == 4.
Don't forget the BigInteger for very long values.
return new BigInteger(s1).compareTo(new BigInteger(s2));
Integer.compareTo sorts numbers numerically. This is what you want.
String.compareTo sorts strings lexicographically; that is, in alphabetical order.
I remember in Windows 3.1 that the folder of photos from my digital camera was ordered like this: PHOTO1, PHOTO10, PHOTO100, PHOTO2, PHOTO20, PHOTO3, ... and so on. Windows XP sorts them more like you would expect: PHOTO1, PHOTO2, PHOTO3, ... etc. This is because it has special sorting rules for strings that represent numbers.
In lexicographical ordering, each character in one string A is compared to the corresponding character in another string B. For each corresponding character in the two strings:
- If A's current character is lexicographically less than (comes before in the alphabet) B's character, then A comes before B.
- If B's character is less than A's character, then B comes before A.
- If the two characters are the same, then we don't know yet. The next one is checked.
- If there are no more characters left in one of the strings, then the shorter one comes before the longer one.
- If there are no more character left in both strings, then they are the same string.
The fourth point here is why you are getting incorrect answers, assuming Eddie's analysis of your problem is correct.
Consider the strings "10" and "2". Lexicographical ordering would look at the first characters of each, '1' and '2' respectively. The character '1' comes before '2' in the character set that Java uses, so it sorts "10" before "2", in the same way that "bare" is sorted before "hare" because 'b' comes before 'h'.
I suggest you cast your strings to integers before sorting. Use Integer.parseString to do this.
are you sure you want to mix Integers and Strings in the same list? if so, are Integers less or greater than Strings? what is this particular sorting criteria?
you can also make a bubble sort method which sorts distinct lists of Integer and lists of String (and lists of any other class). to do so, you can use Generics. for example:
public static <T> void bubbleSort(List<T> elements, Comparator<T> comparator) {
// your implementation
}
you use the comparator parameter to compare the elements, that's why they can be Integers or Strings (not both at the same time). the compiler won't let you [without any warning] pass a list of objects of one class and a comparator of a different class, so the comparison will always work.
pls try this
Collections.sort(data, new Comparator<TXCartData>() {
@Override
public int compare(TXCartData lhs, TXCartData rhs) {
int n1=Integer.parseInt(lhs.rowId);
int n2=Integer.parseInt(rhs.rowId);
if (n1>=n2){
return 1;
}
return -1;
}
});
Classes that has a natural sort order (a class Number, as an example) should implement the Comparable interface, whilst classes that has no natural sort order (a class Chair, as an example) should be provided with a Comparator (or an anonymous Comparator class).
public class Number implements Comparable<Number> {
private int value;
public Number(int value) { this.value = value; }
public int compareTo(Number anotherInstance) {
return this.value - anotherInstance.value;
}
}
public class Chair {
private int weight;
private int height;
public Chair(int weight, int height) {
this.weight = weight;
this.height = height;
}
/* Omitting getters and setters */
}
class ChairWeightComparator implements Comparator<Chair> {
public int compare(Chair chair1, Chair chair2) {
return chair1.getWeight() - chair2.getWeight();
}
}
class ChairHeightComparator implements Comparator<Chair> {
public int compare(Chair chair1, Chair chair2) {
return chair1.getHeight() - chair2.getHeight();
}
}
Usage:
List<Number> numbers = new ArrayList<Number>();
...
Collections.sort(numbers);
List<Chair> chairs = new ArrayList<Chair>();
// Sort by weight:
Collections.sort(chairs, new ChairWeightComparator());
// Sort by height:
Collections.sort(chairs, new ChairHeightComparator());
// You can also create anonymous comparators;
// Sort by color:
Collections.sort(chairs, new Comparator<Chair>() {
public int compare(Chair chair1, Chair chair2) {
...
}
});