How to search in a custom built arraylist? - java

I have an arraylist built like this:
In class: Strings.java
ArrayList<MyQueue> strings = new ArrayList<MyQueue>();
strings.add (new MyQueue("paper", "clips", "eraser"));
strings.add (new MyQueue("paperplane", "numbers", "pineapple"));
In class: MyQueue.java
--Constructor with 3 string parameters--
--Getters/setters for three strings--
Now in the Strings.java class, I want to search my ArrayList "strings" to see if it has the string "paper"?
How could I do this efficiently?

You should try to override the equals method to compare the objects using the first attribute. And then call contains method to check for the object that has "paper" attribute. contains method uses equals internally so that's the reason you need to override equals.

iterate through strings to get each MyQueue and then iterate through the elements in each MyQueue to see if it has "paper"
for(MyQueue mq:strings){
if(mq.getString1().equals("paper") ||
mq.getString2().equals("paper") ||
mq.getString3().equals("paper") )
return true;
}
return false;
where getString#() is the method for getting each of the Strings in MyQueue

Related

Check if String is in Arraylist

How can I check if my Input String is in my ArrayList?
I did it like this. But it always shows "not equal". Althoug I insert 1 for example:
public class Main {
public static void main(String[] args) {
String Input = JOptionPane.showInputDialog("Input:");
ArrayList<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
if (Input.equals(list)) {
JOptionPane.showMessageDialog(null, "equals");
} else {
JOptionPane.showMessageDialog(null, "not equal");
}
}
}
If you want to check does List<T> contains T item you should use yourList.contains(T item) in your code, you are using item.equals(object) which is completely different. In short what equals() does is it checks do both objects are stored in the same memory address. Although for some default classes this method is overwritten and works a different way, String class is a good example of that.
Explanation
You wrote
if (Input.equals(list)) { ... }
with Input being a String and list an ArrayList. But, the String#equals (documentation) method compares if two Strings have the same characters (like "hello".equals("hello")), not if the argument list contains the element you called the method on. To quote from its documentation:
Compares this string to the specified object. The result is true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.
Solution
What you actually want to use is List#contains (documentation):
Returns true if this list contains the specified element. More formally, returns true if and only if this list contains at least one element e such that Objects.equals(o, e).
So the code might look like:
if (list.contains(Input)) { ... }
Naming convention
Please note naming conventions. Variable names should always be in camelCase, so input instead of Input. Same for method names.
Only class names are written in PascalCase. And constants (static final) are written in uppercase SNAKE_CASE.

What does boolean do under these circumstances?

public static boolean containsAll(String[] strings, String test)
{
if (test == null || strings.length == 0) {
return false;
}
for (String str : strings)
if (!test.contains(str))
return false;
return true;
}
I have no idea what I can add to a boolean inside the parentheses but I have this line of function in my script with help from a fellow SOF member.
Thing is, how do I know what to write in a parenthesis to declare stuff? I don't know the rules from my memory and I don't have any source I can relate to. Basically I have no idea why there is an array and a string declared in the parentheses.
Basically,
1) Why is there a line declaring an array and a string inside the parentheses?
2) Where can I relate to as a source to get more information about classes like "boolean" and what I can do to change their functions? Basically I want a book-like website I can relate to whenever I don't know about something in java.
Why is there a line declaring an array and a string inside the parentheses?
So that you can use those parameters within the method , to achieve something .
From the method declaration it seems :
public static boolean containsAll(String[] strings, String test)
The method tries to search for a String passed as parameter test within an array passed as parameter strings and returns boolean true or false depending on whether the strings array contains the test String or not. Or probably , the method was named containsAll() to signify that it ascertain whether all the elements of strings array contains test string !
EDITED: The method checks if all the elements of the strings array contains the test String.
Where can I relate to as a source to get more information about classes like "boolean" and what I can do to change their functions
boolean is primitive , Boolean is a wrapper class. Your method returns boolean primitive.

How can println print an object

{
List list= new ArrayList();
list.add("one");
list.add("second");
System.out.println(list);
}
How can the object "list" be used like it has been in the print statement? Don't we need to use the object to access a method to print the list?
prinln(someObject) will print out whatever is implemented in someObject's toString() method.
You can use toString() which is (supposed) to be implemented for all objects:
System.out.println(list.toString())
Note that you ought not to use the returned string as anything you can actually parse; it's really for a visual representation. It also doesn't need to uniquely represent the object.
When you write
System.out.println(list)
you are, in fact, using the toString() method implicitly.
Docs Says about toString() in Collections:
Returns a string representation of this collection. The string representation consists of a list of the collection's elements in the order they are returned by its iterator, enclosed in square brackets ("[]"). Adjacent elements are separated by the characters ", " (comma and space). Elements are converted to strings as by String.valueOf(Object).
When we pass any object to println() method, it will implicitly call that object's toString() method. So, what is actually executed is
System.out.println( list.toString() );
ArrayList is inherited from the class java.util.AbstractCollection and that class has toString() method. So, in your case, that toString() should be executed.
That toString() method returns a string representation of this collection. The string representation consists of a list of the collection's elements in the order they are returned by its iterator, enclosed in square brackets ("[]"). Adjacent elements are separated by the characters ", " (comma and space). Elements are converted to strings as by String.valueOf(Object).
Looking at your question and comments, I think your confusion ultimately stems from you being unsure how printing works. In general in such cases, I recommend to get the JDK sources and simply take look inside.
In this case, we would first go to the System class and check out the out member (because println is called on System.out):
public final class System {
...
public final static PrintStream out = null;
Since we know now that out is a PrintStream, let's check out that class:
public class PrintStream extends FilterOutputStream
implements Appendable, Closeable
{
...
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
(we know it's calling this method, since the other println signatures don't match the type List)
OK, so we see that println converts the given Object (your List in this case) to a String using String.valueOf(Object). Let's check out that method:
public final class String {
...
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
So now we know that your List's toString() method is used to generate the output. As others have pointed out, it is overriden in ArrayList to provide the output you see.
It can be used like this because class List inherits the Object class, and the Object class has the toString() method, which means every object can be turned into a String.
printing a list directly will give the the string representation of the list.
If you want to access the objects in the list you need to use iterator or loops or advanced for loops for collections.
e.g.
for(String s : list){
System.out.println(s);
}
Well you can study and try out all the list methods to modify it. e.g. add, remove.
Also if you are printing an object, then toString() method is implicitly called.
You can loop through all the items in the list in order to print them out. you can do this using a while loop of a for loop.
while (list.hasNext) {
System.out.println((String) list.next());
}
for(String i in list){
System.out.println(i) ;
}
Not sure if this is what your looking for but its an option.
Yo need toString() method. when you print object Reference , by default toString() method is called. If you look at toString() method by default it prints
getClass().getName() + '#' + Integer.toHexString(hashCode())
Now as per your requirements you can override this to print the values in list(String Class overrides it too)
Here you are creating List interface.So it will allow to add duplicate values in list also.Also we can directly print object like System.out.println(obj);
And inside the List class the, toString method is being overridden so that it will print all its contents rather than the address of the object.
System.out.println(Arrays.toString(myList.toArray()));

Search method always null

I'm having issues with a method I've written to search a class called Item. No matter what I search, it is returning null. I believe I'm having issues with variable scope:
public Item search(String itemSearch) {
Item search = null;
for(Item i : items){
if (i.getName() == itemSearch){
search = i;
}
}
return search;
}
The getName method returns the name attribute of the item. No matter what the Item search is always null, I'm guessing this is due to variable scope and it is not assigning in the for each loop? Why is this method always null?
Thank you
You can't use the == to compare the content of two strings in java. You need to use the .equals() method
Using the == will only compare the adress of the two strings, while equals will compare their values.
You are comparing strings using ==. You should instead use equals() method. E.G
i.getName().equals(itemSearch)
Also instead of looping the entire loop use return i in the if statement, instead of assigning i to search and then returning search.

java - How to find matching objects between two lists?

Given two Lists, each list holding the same object type, I would like to find objects between the two lists that match, based on some property values.
e.g. an object from List1, L1Obj, matches an object from List2, L2Obj, if L1Obj.a == L2Obj.a AND L1Obj.b == L2Obj.c AND L1Obj.c == L2Obj.c
These properties are not the only properties of the of the class, but are all that is needed to uniquely identify an object within a list.
My question is - what is the best way to achieve this?
One way would be to construct to HashMaps based on the lists, with the concataned String value of a+b+c used as the key to index an object. That way I could iterate through the first list, and attempt to lookup an object in the second list with the same key.
How does this sound? Is there a better way of achieving this??
All help is much appreciated!
UPDATE:
Okay, so actually I need a bit more. Upon finding a match, I want to overwrite properties L1Obj.x, L1Obj.y, L1Obj.z with those of L2Obj. HashSet sounds great for finding that matches, but if I'm right it doesn't actually allow me to access these matches.
What can I do about this?
Do the objects you want to look at implement equals(Object) and hashCode() that only take into account the fields you care about? If so, you can create a new HashSet from the first list, and then call retainAll() passing in the second list.
If they don't implement equals(Object) and hashCode() with respect to the properties you care about, you can create a TreeSet and pass in a Comparator that looks at the properties you care about.
Rather than use the String repesntation, use the equals() method a HashSet as so:
class MyObj {
Property a;
Property b;
Property c;
public boolean equals(Object o) {
// use == if Property is primitive, like int or something
return o instanceof MyObj && a.equals(o.a) && b.equals(o.b) && c.equals(o.c);
}
// edit - when you override equals, also override hashcode
public int hashCode() {
return a.hashCode() ^ b.hashCode() ^ c.hashCode();
}
public String toString() {
return a.toString() + " " + b.toString() + " " + c.toString();
}
}
// later in your main method
Set<MyObj> objSet = new HashSet<MyObj>();
for(MyObj o : list1) objSet.add(o);
for(MyObj o : list2) if(objSet.contains(o)) System.out.println(o + " is a match!");
You can do one thing. Have two lists with these objects and override the equals method of the class to which these objects belong.
Your equals method should look like
#Override
public boolean equals(Object obj)
{
return (this.a == obj.a && this.b == obj.b && this.c == obj.c)
}
Also remember, once you override equals method, you need to override int hashCode() method as well.
One thing to note is while implementing hashCode() is that 2 equal objects will have same hashCode, while the converse is not true.
I don't know if I thinking to easy but I would try it like that:
Override the equals method of the object to implement your comparison to check if it is the same object
Then I would iterate over the first list and check with the contains method if the object is also contained in the second list.
Then I would iterate through the second list and check if the object is also in the first list and not already in the result list.
The object in question should implement the boolean equals(Object) method. E.g.:
L1Obj.equals(L2Obj);
You could overload that method so that you can implement the equality operations that you want.

Categories

Resources