Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I've a doubt about how ArrayList contains method works. Let's take an example:
List<String> lstStr = new ArrayList<String>();
String tempStr1 = new String("1");
String tempStr2 = new String("1");
lstStr.add(tempStr1);
if (lst.contains(tempStr2))
System.out.println("contains");
else
System.out.println("not contains");
it returns 'not contains'.
Another example:
List<LinkProfileGeo> lst = new ArrayList<LinkProfileGeo>();
LinkProfileGeo temp1 = new LinkProfileGeo();
temp1.setGeoCode("1");
LinkProfileGeo temp2 = new LinkProfileGeo();
temp2.setGeoCode("1");
lst.add(temp1);
if (lst.contains(temp2))
System.out.println("contains");
else
System.out.println("not contains");
It returns contains. So how does contains method works ?
Thanks
You are adding your string to the list lstStr
lstStr.add(tempStr1);
but you are using contains method on lst
if (lst.contains(tempStr2))
Your idea of testing is correct, as contains internally uses equals to find the element, so if the string is matched using equals then it should return true. But it seems you are using two different lists, one for adding and another one for checking contains.
Here is the relevant source code from ArrayList if you're interested. As #user2777005 noted, you had a typo in your code. You should use lstStr.contains(), NOT lst.contains().
public int indexOf(Object o) {
if (o==null) {
for (int i=0; i<a.length; i++)
if (a[i]==null)
return i;
} else {
for (int i=0; i<a.length; i++)
if (o.equals(a[i]))
return i;
}
return -1;
}
public boolean contains(Object o) {
return indexOf(o) != -1;
}
the second part is a duplicate of: How does a ArrayList's contains() method evaluate objects?
You need to override the equals method to make it work as you desire.
in first section of code :
String tempStr1 = new String("1");
String tempStr2 = new String("1");
both tempStr1 and tempStr2 refer two different-2 object of string. after that String object that is refered by tempStr1 is added to the List by the codelstStr.add(tempStr1); .so the List have only one String object that is reffered by tempStr1 not tempStr2.but
contains(); method work on equals() method.that is lstStr.contains(temp2); return true if content of String object which is refered by temp2 is same as the one of content of String object which is added to the List and return false when matching not found.here lstStr.contains(temp2);return true because content of String object temp2 is equal to content of String object temp1 which is added to List.but in your code insteed of lstStr.contains(temp2); it is mentioned as:
lst.contains(temp2);
Here you are using different List reference variable (lst) instead of (lstStr).thats why it return false and executed else part.
in 2nd section of code setGeoCode() is not defined.
Related
I've been developing a small application for work, and I've come across something I can't figure out.
In the following code, I have an ArrayList of a Custom Class called 'Product' that contains data of type 'String'. I use the .contains method on this ArrayList to ensure it doesn't contain a certain String.
My IDE gives me the warning of 'Suspicious call to java.util.Collections.contains: Given object cannot contain instances of String (expected Product)'.
I completely understand the above message, because I'm comparing two different Types, so how can it ever evaluate correctly? I'm thinking it must be because the 'Product' class contains the data I want to compare, it is defaulting to using the toString method on the Product class (I override this in the Class) and comparing it with the String I want to compare it against.
It seems like JVM black magic to me.
private void createOrderListing(List<String[]> orderList)
{
//For each line of the order list file
for(String[] s : orderList)
{
if(s.length >= 28) //OrderLine should be of this length
{
if (!s[0].equalsIgnoreCase("ProductCode") && !s[0].isEmpty()) //Makes sure we're not including headers
{
//How does this bit work?
if(!productListing.contains(s[0]))
{
OrderLine order = new OrderLine();
//References product code of Product against Order Line, if match, then pack sizes and other basic fields ammended as appropriate
boolean productFound = false;
for (Product p : productListing)
{
if (s[0].contentEquals(p.getProductCode()))
{
order.initialAmendOrderLine(p.getProductCode(), p.getProductName(), p.getPackSize(), p.getProductType());
productFound = true;
}
}
if(productFound)
{
order.setOrderValues(s);
orderListing.add(order);
}
}
//System.out.println("\nOrder Product is: " + order.getProductName()+ "\nOrder Pack Size is: " + order.getInternalPackSize());
}
}
}
}
UPDATE
The reason this works as pointed out in the comments is that the block is always true (the .contains method is always false, the ! inverses this, hence true). Sorry for the confusion and pointing out my carelessness.
Here is an implementation of contains method in ArrayList that I have in OpenJDK:
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
Basically, there is nothing complex in it. It iterates through the all elements of your ArrayList and checks whether your given object is equal to the current one. If the condition is true then element exists in the list.
So let's imagine that you are passing String "SomeValue" to this method. Elements of ArrayList are iterated and following action is executed: "SomeValue".equals(elementData[i]) where elementData[i] is a product.
Since equals method of String class cannot compare String with a Product it returns false and as a result, you get false from contains method.
To fix this situation you can iterate over ArrayList manually and compare some Product's field with your string. E.g. you can implement following contains method:
public boolean contains(List<Product> products, String yourStringValue) {
for (Product p : products) {
if(p.getProductCode().equals(yourStringValue)){
return true;
}
}
return false;
}
productListing is a list of Product objects. Yet you are asking the list if it contains a specific String object -- which shouldn't ever happen.
What you should do is check if your Product#getProductCode is equal to your specific String. This can be acheived by using streams:
if(!productListing.contains(s[0])) // replace this
// with this
if (!productListing.stream().filter(o -> o.getProductCode().equals(s[0])).findFirst().isPresent())
What does this code do? It checks all your Product elements to find one whose myStringData attribute is equal to the String you're comparing.
since contains relays on equals implementation, when you do
if(!productListing.contains(s[0]))
you are asking the list OF ARRAYS OF STRINGS if its contains a String.
that will return always false because the type are different, so is not that is working at all, is that your condition will always return false
This question already has answers here:
Searching in a ArrayList with custom objects for certain strings
(9 answers)
Closed 9 years ago.
I'm having an list of Object type. In that I have one String property idNum. Now I want to get the index of the object in the list by passing the idNum.
List<Object1> objList=new ArrayList<Object1>();
I don't know how to give objList.indexOf(// Don't know how to give here);
Is it possible to do this without iterating the list. I want to use indexOf() method only.
Write a small helper method.
private int getIndexByProperty(String yourString) {
for (int i = 0; i < objList.size(); i++) {
if (object1 !=null && object1.getIdNum().equals(yourString)) {
return i;
}
}
return -1;// not there is list
}
Do not forget to return -1 if not found.
Implement equals (and hashCode) in Object1 class based on idNum field, then you use List.indexOf like this
int i = objList.indexOf(new Object(idNum));
or make a special class for seaching
final String idNum = "1";
int i = list.indexOf(new Object() {
public boolean equals(Object obj) {
return ((X)obj).idNum.equals(idNum);
}
});
You cannot do this with indexOf. Instead all of the objects in the list should inherit from a common interface - for example
interface HasIdNum {
String getIdNum();
}
Now you list can be List<HasIdNum> and you can loop through it to find the object by id using:
for (HasIdNum hid: objList) {
if (hid.getIdNum().equals(idNumToFind) {
return hid;
}
}
return null;
To get the index rather than the object do:
for (int i=0;i<objList.size();i++) {
HasIdNum hid = objList.get(i);
if (hid.getIdNum().equals(idNumToFind) {
return i;
}
}
return -1;
Alternatively you can use reflection to query the methods of the object, but that will be much slower and much less safe as you lose all the compile time type checking.
From what I know, object clone() creates a new copy of the cloned object. In my case I'm trying to clone the matrix of Symbol (which is a simple enum). this.table is the original object, while t is the clone. When I write a new value into a cell of t I would expect that this.table remains unchanged. However this is not the case and the second assert fails. (I added the first assert only to ensure the correctness of the second one).
Here is the code:
#Override
public State applyAction(Action action) {
int x = ((TickAction)action).x;
int y = ((TickAction)action).y;
Symbol[][] t = this.table.clone();
assert this.table[x][y] != currentPlayer.getSymbol();
t[x][y] = currentPlayer.getSymbol();
assert t[x][y] != this.table[x][y] ;
TableState ts = new TableState(t,this.currentPlayer.getNextPlayer());
ts.setLastAction(action);
return ts;
}
Note: with debugger I checked that t and this.table actually have different id, however after a second check I noticed that, despite this, their single cells have the same id. Then I'm much confused about this. Could someone explain me what's happening?
You have an array of arrays of Symbol instances.
When you call clone() on this.table, you get a new array, t, but each of the arrays in t is the same as the array in this.table.
In order to check that, you can try assert t[0] == this.table[0];.
In order to get a deeper clone, you would have to create a new array and initialize it yourself:
Symbol[][] t = new Symbol[][this.table.length];
for (int i = 0; i < t.length; i++)
{
t[i] = new Symbol[this.table[i].length];
for (int j = 0; j < t[i].length; j++)
{
// Here I am sharing the Symbol objects between the two arrays.
// If you do not want that, define your own way to copy or clone the object.
t[i][j] = this.table[i][j];
}
}
I'm just guessing here, but Java makes a distinction between == and .equals() and everyone gets burned once or twice using == with some object reference that actually needs .equal. Give this a try...
assert this.table[((TickAction)action).x][((TickAction)action).y].equals( currentPlayer.getSymbol() );
you cant use clone as is, it wont help you if you did not implemented it yourself.
same for equals(except strings)
I want to check to see if two arrays share at least one term in common for my program.
I'm not quite sure what the code is to compare two arrays, but here is what I have so far;
if ((modWikiKeyArray).equals(inputArray[0]))
{
StringBuilder hyperlinkBuilder = new StringBuilder();
for(int i = 0; i < modWikiKeyArray.length; i++)
{
hyperlinkBuilder.append(modWikiKeyArray[i]);
}
}
How would I compare the array modWikiKeyArray to inputArray just to check and see if inputArray[0] is equal to any term inside of modWikiKeyArray?
Arrays.asList lets you build a list backed by an arbitrary array and use convenient Java Collections Framework features like the contains method:
Arrays.asList(oneArray).contains(elementFromAnotherArray)
If you want to see if the arrays have at least one element in common, you could build a HashSet out of one and loop over the other to try to find a common element:
boolean arraysIntersect(Object[] array1, Object[] array2) {
Set array1AsSet = HashSet(Arrays.asList(array1));
for (Object o : array2) {
if (array1AsSet.contains(o)) {
return true;
}
}
return false;
}
You can do the following
for(int i=0;i<modWikiKeyArray.length;i++) {
if(modWikiKeyArray[i].equals(inputArray[0])) {
System.out.println("Match found");
}
}
Note you need to override the equals() method of whatever array you are creating(Class of which array you are creating) .
Going by your code snippet, it looks like you need to check the presence of inputArray[0] only, in which case the following is sufficient:
boolean exists = java.util.Arrays.asList(modWikiKeyArray).contains(inputArray[0]);
Alternatively, you might also want to use ArrayUtils from Apache commons-lang:
boolean exists = ArrayUtils.contains(modWikiKeyArray, inputArray[0]);
However, if I read the text of your question, it seems you want to find if modWikiKeyArray contains at least one item from inputArray. For this you may also use retainAll from the Collections API to perform a list intersecion and see if the intersection list is non-empty.
However, the most primitive is still Aniket's method. However, I will modify it to reduce unnecessary operations:
int i = modWikiKeyArray.length - 1;
MyObject inputElement = inputArray[0];
boolean found = false;
for(; i != 0; i--) {
if(modWikiKeyArray[i].equals(inputElement)) {
found = true;
break;
}
}
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I am implementing a String matching algorithm for a username database. My method takes an existing Username database and a new username that the person wants and it checks to see if the username is taken. if it is taken the method is supposed to return the username with a number that isn't taken in the database.
Example:
"Justin","Justin1", "Justin2", "Justin3"
Enter "Justin"
return: "Justin4"
since Justin and Justin with the numbers 1 thru 3 are already taken.
In my code sample below, newMember returns Justin1 even though it already exists--where is the mistake?
public class UserName {
static int j = 0;
static String newMember(String[] existingNames, String newName){
boolean match = false;
for(int i = 0; i < existingNames.length; i++){
if(existingNames[i] == (newName)){
match = true;
}
}
if(match){
j++;
return newMember(existingNames, newName + j);
}
else{
return newName;
}
}
public static void main(String[] args){
String[] userNames = new String[9];
userNames[0] = "Justin1";
userNames[1] = "Justin2";
userNames[2] = "Justin3";
userNames[3] = "Justin";
System.out.println(newMember(userNames, "Justin"));
// I don't understand why it returns Justin1 when the name is already taken
// in the array.
}
}
This line:
if(existingNames[i] == (newName)){
Should become
if(existingNames[i].equals(newName)){
In general, always use equals instead of == for Strings in Java.
I would change your approach to this. I think it would be better to use a Map<String, Integer>. For example, the fact that "Justin" - "Justin3" are taken usernames can be represented by the map:
{"Justin": 3}
To check if a username is taken, check if it's a key in the map. To get the "next" username for a specific taken username, get the value corresponding to the name from the map and add 1. Something like this:
static String newMember(Map<String, Integer> existingNames, String newName) {
if (existingNames.containsKey(newName)) {
int newNum = existingNames.get(newName) + 1;
existingNames.put(newName, newNum);
return newName + newNum;
}
existingNames.put(newName, 0);
return newName;
}
Oh, and use .equals() instead of == when comparing strings :)
*Never ever compare equality of Strings with ==. use equals() *
Use .equals to compare strings in Java, not ==.
== will determine if the string references are the same which they almost certainly will not be. (There are rare cases when they may be due to the intern pool.)
.equals will determine if the content of the strings are the same.
When comparing strings in Java, you should generally use the equals() methods to do so.
Using == with strings compares the references, not the underlying objects. Use str.equals().
I guess you have a function somewhere in your application answering if a username already exists, I call this usernameExists(String username) returning true or false.
String getOkUsername (String wantedUsername) {
//if it's free, return it!
if(!usernameExists(wantedUsername)) {
return wantedUsername;
};
//OK, already taken, check for next available username
int i=1;
while(usernameExists(wantedUsername+Integer.toString(i))) {
i++;}
return wantedUsername + Integer.toString(i);
}
You're not comparing the strings correctly, and you're adding the integer 1 to a string. Comparing strings is done with .equals. In order to concatenate the integer onto the end of the string:
static Integer j=0;
return newMember(existingNames, newName + j.toString());
It is much easier to do it in SQL:
select ... where ... LIKE username%