int [] nir1 = new int [2];
nir1[1] = 1;
nir1[0] = 0;
int [] nir2 = new int [2];
nir2[1] = 1;
nir2[0] = 0;
boolean t = nir1.equals(nir2);
boolean m = nir1.toString().equals(nir2.toString());
Why are both m and t false? What is the correct way to compare 2 arrays in Java?
Use Arrays.equals method. Example:
boolean b = Arrays.equals(nir1, nir2); //prints true in this case
The reason t returns false is because arrays use the methods available to an Object. Since this is using Object#equals(), it returns false because nir1 and nir2 are not the same object.
In the case of m, the same idea holds. Object#toString() prints out an object identifier. In my case when I printed them out and checked them, the result was
nir1 = [I#3e25a5
nir2 = [I#19821f
Which are, of course, not the same.
CoolBeans is correct; use the static Arrays.equals() method to compare them.
Use Arrays.equals instead of array1.equals(array2). Arrays.equals(array1, array2) will check the content of the two arrays and the later will check the reference. array1.equals(array2) simply means array1 == array2 which is not true in this case.
public static boolean perm (String s, String t){
if (s.length() != t.length()) {
return false;
}
char[] perm1 = s.toCharArray();
Arrays.sort(perm1);
char[] perm2 = t.toCharArray();
Arrays.sort(perm2);
return Arrays.equals(perm1, perm2);
}
boolean t = Arrays.equals(nir1,nir2)
I just wanted to point out the reason this is failing:
arrays are not Objects, they are primitive types.
When you print nir1.toString(), you get a java identifier of nir1 in textual form. Since nir1 and nir2 were allocated seperately, they are unique and this will produce different values for toString().
The two arrays are also not equal for the same reason. They are separate variables, even if they have the same content.
Like suggested by other posters, the way to go is by using the Arrays class:
Arrays.toString(nir1);
and
Arrays.deepToString(nir1);
for complex arrays.
Also, for equality:
Arrays.equals(nir1,nir2);
Use this:
return Arrays.equals(perm1, perm2)
Instead of this:
return perm1.equals(perm2);
Please have to look this
Related
I found the code below from this SO question. It has worked great so far, but I have come across the need to shuffle arrays of strings. The code below only accepts arrays of ints as a parameter. I am still very new to java and I can't seem to figure out how to let the method accept multiple datatypes in it's parameters. It would be wonderful if I could use the same method to shuffle arrays of ints AND arrays of strings. Can anyone help?
static int[] shuffle(int[] ar) {
// If running on Java 6 or older, use `new Random()` on RHS here
Random rnd = ThreadLocalRandom.current();
for (int i = ar.length - 1; i > 0; i--)
{
int index = rnd.nextInt(i + 1);
// Simple swap
int a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
return ar;
}
You should have different methods for different parameters. This will be method overloading.
In your case (for strings and int)
static int[] shuffle(int[] array)
static String[] shuffle(String[] array)
Or you can have Object array in argument of your method. That way you have to define your int array as Integer class array in calling method.
static Object[] shuffle(Object[] array)
Object is the superclass of all classes in Java and subclass' object can be handled by superclass' reference.
Since int is primitive type, not a class, you have to define int array as Integer array. Integer is type wrapper class for int.
You can have two different methods. One that shuffles arrays of ints and one that shuffles arrays of strings.
static String[] shuffleStringArray(String[] ar){
//method logic goes here
}
The basic structure of your method shouldn't change too much.
Good luck!
Java solves this problem by making arrays covarient. This means that if B is a subtype of A the B[] is a subtype of A[]. This means that you can make you parameter type Object[] and you can pass in any array of object. For primitive types like int you still need to write a separate method however because primitives are not objects.
Use a generic array this way
static <T> T[] shuffle(T[] ar){
// If running on Java 6 or older, use `new Random()` on RHS here
Random rnd = ThreadLocalRandom.current();
for (int i = ar.length - 1; i > 0; i--)
{
int index = rnd.nextInt(i + 1);
// Simple swap
T a = ar[index];
ar[index] = ar[i];
ar[i] = a;
}
return ar;
}
Invoke it like so:
System.out.println(Arrays.toString(shuffle(new Integer[]{1,2,3,4})));
(or)
System.out.println(Arrays.toString(shuffle(new String[]{"a","b","c"})));
You cannot do that if you need to support both objects and primitives. You need to create an overloaded method for each primitive type and one for Object. Each version of this method will re-implement the same algorithm with diferent data types.
Your method is analogous to the ones in java.util.Arrays class. Take a look at Arrays.java source code from Open JDK.
http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/be44bff34df4/src/share/classes/java/util/Arrays.java
You can't have a method perform the same operations on an int array and a reference type array, because Java treats those as completely different types, and their common superclass (Object) lacks functionality as an array. However, you seem to be getting at overloading (see Overloading Methods part). You can have a seperate implementation of the method for different parameters. Simply copy/paste your code and replace relevant instances of int with String. This is actually what is done for the primitive type arrays in Arrays.copyOf.
public int compareTo(Person p) {
int res = 1;
String personStr = p.getId();
String thisId = this.getId();
if(thisId.equals(personStr)){
res = 0;
}
else if(thisId.compareTo(personStr)){
res = -1;
}
return res;
}
A quite simple compareTo method I have implemented but I don't get the error message. The condition in the else if statemint gives me a message saying that it can't convert from int to boolean. I get that, but the thing is that I'm using netiher. I just want to compare 2 simple strings, why does this happen?
What you should notice is that the interface 'compareTo' is returning an int 'public int compareTo' being the sign
if statements rely on a boolean value, however you use thisId.compareTo(personStr) which will return an integer, just like the method you are creating.
Your first if statement is fine - 'equals' returns a boolean. However the second does not, it will likely return either a -1, a 0 or a 1.
but the thing is that I'm using netiher
Are you sure about that?
This results in an int:
thisId.compareTo(personStr)
But you're using it as a Boolean:
if (yourResult)
An if statement requires a boolean, it can't just be used on any value. For example, consider the difference between this:
if (value == 1)
and this:
if (value)
In some languages you can get away with that. Some languages assign degrees of "truthiness" to all types, allowing you to use them in boolean expressions. Java is not one of them. You have to explicitly define your boolean logic in Java:
if(thisId.compareTo(personStr) > 0) // or whatever your logic should be
if you just want to compare those 2 strings why not use
public int compareTo(Person p) {
String personStr = p.getId();
String thisId = this.getId();
return thisId.compareTo(personStr);
}
I thought the Collections.binarySearch()would return never return a 0 cause the comparison in the comparator is between two Integer which the == operation would always been false, but the run results let me down... Can someone help me out?
public class ObjectCompare {
static Comparator<Integer> com = new Comparator<Integer>(){
public int compare(Integer i, Integer j) {
return i<j?-1:(i==j?0:1);// i thought i==j would never return true
}
};
public static void main(String[] args){
String[] array = {"0","1","2","3","4","5"};
List<Integer> list = new ArrayList<Integer>();
Integer k = new Integer(1);
Integer l = new Integer(1);
System.out.println(k==l); // this return's false
for(String s : array)
list.add(Integer.valueOf(s));
System.out.println(Collections.binarySearch(list,1,com));// this returns 1
}
}
If I understand well, the question is "why does the binarySearch actually find the item in the list, when my comparator compares instances?" Right?
Well, the answer is as simple as that: because actually it compares two identical instances (references). Integer class maintains a pool of cached instances for values between -128 and 127 (inclusive). This pool of instances is always used when valueOf is called with an argument between these values.
Here you have 2 calls to valueOf(1) (more or less explicit) in your code.
One is here: list.add(Integer.valueOf(s));. For one iteration through the loop, the call is actually list.add(Integer.valueOf("1"); Behind the scenes, valueOf(int) is called.
And the second is here: Arrays.binarySearch(array,1,com). The boxing operation from the literal 1 to the Integer instance is actually performed via an invocation of valueOf(int).
System.out.println(k==l);
This would return false as they are different objects. As known, you need to use equals() method to compare the values of two Integer objects.
return i<j?-1:(i==j?0:1);
This is the return statement of the compare() method. i will not be equal to j unless the same object is present in twice in the list. Note that the compare() method is called by the Collections.sort(list, comparator) method internally. This is not called by the binarySearch() method directly.
System.out.println(Collections.binarySearch(list,1,com));
This returns 1, but the 1 here represents the index at which the search item was found. It would return 3 if your search item was System.out.println(Collections.binarySearch(list,3,com));. The 1 returned by binarySearch() is not from the compare() method. The binary search algorithm will internally call the equals() method to compare the Integer values during the search.
Hence, the i == j clause in the compare() which you thought would never satisfy, has nothing to do with the actual binary search which is performed on the list of Integers.
From the docs of Collections.binarySearch(List, searchItem, comparator):
Searches the specified list for the specified object using the binary search algorithm. The list must be sorted into ascending order according to the specified comparator (as by the sort(List, Comparator) method), prior to making this call.
use this
System.out.println(k.equals(l)); // this return's true
instead of
System.out.println(k==l); // this return's false
because == this compare the address of your integer objects not value...
return i<j?-1:((i.equals(j))?0:1);// i thought i==j would return true
instead of
return i<j?-1:((i==j)?0:1);// i thought i==j would never return true
Integer is the boxed variant of int, i.e. a reference type. You need to use the Integer#equals method to test for equality as == will just test if the references are equal:
static Comparator<Integer> com = new Comparator<Integer>(){
public int compare(Integer i, Integer j) {
return i < j ? -1 : (i.equals(j) ? 0 : 1);
}
};
Edit
Now that I think about it, writing a Comparator for Integer is kind of pointless, since Integer already implements Comparable<Integer>.
I've taken the liberty to re-shape the program to focus on the question at hand: the i == j in the compare() method:
import java.util.Arrays;
import java.util.Comparator;
public class StackOverflow {
static Comparator<Integer> com = new Comparator<Integer>(){
#Override
public int compare(Integer i, Integer j) {
int res = 0;
if(i<j){
res = -1;
} else if(i == j ){
res = 0;
} else {
res = 1;
}
return res;
}
};
public static void main(String[] args){
Integer[] array = {0,1,2,3,4,5};
System.out.println(Arrays.binarySearch(array,1,com));
}
}
If you debug/step through the code you do see that when comparing 1 with 1, the code goes into the res = 0. This is likely to be an autoboxing quirck? Maybe as it has to auto-unbox them for i
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
thank you for taking the time to read this. Sorry if my question is dumb, I tried searching but couldn't quite figure out why I'm having this problem. I was trying to test some code for another application, but I'm having issues. Perhaps I just don't understand arrays properly.
I have a method named halfStepUp in a class named Transpose that, for testing purposes, should return "c#" if given "c" and "d#" if given "d". This is the code:
public class Transpose{
public static String halfStepUp(String note){
String n = null;
if (note == "c") n = "c#";
if (note == "d") n = "d"#;
return n;
}
}
I have the following code in my main method:
String [] scale = new String[2];
scale[0] = "c";
scale[1] = "d";
System.out.println(Transpose.halfStepUp(scale[0]));
This prints "null." What am I doing wrong?
I know the method works because if I use
System.out.println(Transpose.halfStepUp("c"));
It works fine. The solution is probably embarrassingly easy but I couldn't find a good way to word it when searching for help.
Thanks again for reading, and any answers are greatly appreciated!
To add a little more info to the answers you already got:
Java has two types of storage. One is the stack, which includes variable names and their values. One is the heap, that is just a huge collections of free-floating objects.
Now, if you're working with primitive types (like int, boolean or char), assigning a variable like
int myInt = 1;
pushes that variable on thje stack - the name is myInt, the value is 1.
If you, however, have an object (like strings are), assigning a variable does a little bit more.
String myString = "Hey!";
now creates an object (instance of String) somewhere on the heap. It has no name there, only some address in the memory where it can be found.
In addition to that, it pushes a variable on the stack. The name is myString - and the value is the address of the object on the heap.
So why is this relevant to comparing variables? Because == compares values of variables. ON THE STACK, that is. SO if you compare primitive types, everything works as expected. But if you're comparing Objects, == still only compares the values of the variables - which is, in that case, the addresses to the objects. If the addresses are the same, it returns true. That does mean, both variables point to the same object. If the addresses are different, == returns false., Without ever looking at the heap, where the objects really are.
An example:
String a = new String("Hey!");
String b = a;
if (a == b) System.out.println("true");
else System.out.println("false");
will echo "true" - because both variables contain the same object.
String a = new String("Hey!");
String b = new String("Hey!");
if (a == b) System.out.println("true");
else System.out.println("false");
will echo "false" - because you have two objects on the heap now, and a points to the one, while b points to the other. So while the contents of both objects may be the same, the contents of a and b on the stack are different.
Therefore, to compare any object, always use .equals() if you want to compare contents, not instance-equality.
[Addendum]:
With strings, this is even more complicated. As you already found out already,
String a = "Hey!"; // mention the difference to the example above:
String b = "Hey!"; // I did NOT use the `String()` cosntructor here!
if (a == b) System.out.println("true");
else System.out.println("false");
will actually give you "true". Now why is THAT? One might think that we still create two objects. But actually, we are not.
String is immutable. That means, once a String has been created, it cannot be modified. Ever. Don'T believe that? Take a look!
String myString = "test"; // we create one instance of String here
myString += " and more"; // we create another instance of String (" and more")
// and append that. Did we modify the instance stored in
// myString now? NO! We created a third instance that
// contains "test and more".
Therefore, there is no need to create additional instances of String with the same content - which increases performance, as Strings are widely used, in masses, so we want to have as few of them as possible.
To archive that, the JVM maintains a list of String Objects we already created. And every time we write down a String literal (that is something like "Hey!"), it looks in that lists and checks if we already created an instance that has that value. If so, it returns a pointer to that exact same instance instead of creating a new one.
And THIS is, why "Hey!" == "Hey!" will return true.
You should use the .equals() method when comparing strings, not ==. The == operator compares the references to see if they are pointing to the same underlying object. The .equals() method, compares the underlying objects to each other to see if they are semantically equivalent.
Try this instead: (edited from comments)
public class Transpose{
public static String halfStepUp(String note){
String n = null;
if ("c".equals(note)) n = "c#"; //using .equals as a string comparison
if ("d".equals(note)) n = "d#"; //not "d"#
return n;
}
}
The glitch is in this line:
if (note == "c") n = "c#";
This compares strings by address, not by value. Try using "c".equals(note) instead.
class Transpose{
public static String halfStepUp(String note){
String n = null;
if (note == "c") n = "c#";
if (note == "d") n = "d#";
return n;
}
}
public class TransposeTest {
public static void main(String... args) {
String [] scale = new String[2];
scale[0] = "c";
scale[1] = "d";
System.out.println(Transpose.halfStepUp(scale[0]));
}
}
working code
Imagine I have a String array like this:
String[][] fruits = {{"Orange","1"}, {"Apple","2"}, {"Arancia","3"};
If I do this:
for (int i = 0; i < fruits.length;i++){
System.out.println(fruits[i][0].charAt(1));
}
it will print:
r
p
r
And if I do this:
for (int i = 0; i < fruits.length;i++){
Character compare = fruits[i][0].charAt(1);
System.out.println(compare.equals('r'));
}
it will print:
true
false
true
So here is my question. Is it possible to use charAt and equals on the same line, I mean, something like this:
System.out.println((fruits[i][0].charAt(1)).equals("r"));
Regards,
favolas
Yes, provided you convert the result of charAt() to Character first:
System.out.println(Character.valueOf(fruits[i][0].charAt(1)).equals('r'));
A simpler version is to write
System.out.println(fruits[i][0].charAt(1) == 'r');
I personally would always prefer the latter to the former.
The reason your version doesn't work is that charAt() returns char (as opposed to Character), and char, being a primitive type, has no equals() method.
Another error in your code is the use of double quotes in equals("r"). Sadly, this one would compile and could lead to a painful debugging session. With the char-based version above this would be caught at compile time.
Certainly! Try this:
System.out.println((fruits[i][0].charAt(1)) == 'r');
We're doing a primitive comparison (char to char) so we can use == instead of .equals(). Note that this is case sensitive.
Another option would be to explicitly cast the char to a String before using .equals()
If you're using a modern version of Java, you could also use the enhanced for syntax for cleaner code, like so:
public static void main(String[] args) {
String[][] fruits = {{"Orange","1"}, {"Apple","2"}, {"Arancia","3"}};
for (String[] fruit: fruits){
System.out.println((fruit[0].charAt(1)) == 'r');
}
}
The char data type, which is returned from String.charAt() is a primitive, not an object. So you can just use the == operator to perform the comparison as it will compare the value, not the reference.
System.out.println((fruits[i][0].charAt(1) == 'r'));