Why does the method add(<T> element) and remove(Object o) accept different arguments?
For example in a Set<Short> you add short elements. Why does the method remove accepts Object? If you can't add any other data type, why would you remove other data type?
Thank you.
add(<T> element) : to ensure that just a T element is added.
remove(Object o) : you can delete the T element even if it's a referenced by an Object reference.
For instance :
Set<Short> set = new HashSet<Short>();
Short number = 2;
set.add(number);
Object numberObject = number;
set.remove(numberObject) // it will remove 2 from the set.
why would you remove other data type? we're not removing another data type, but we can remove data even if it is referenced by an Object reference (like in the example).
The remove(obj) method, removes the object such that (obj == null ? e ==null : obj.equals(e)) is true. It's because of the equals(Object) method, which takes an Object, that obj and e doesn't have to be of the same type.
Related
I have this :
List<Data<Number, Number>> dataList = new ArrayList<XYChart.Data<Number,Number>>();
List<Data<Number, Number>> dataListSelected = new ArrayList<XYChart.Data<Number,Number>>();
I fill them with some Data<Number,Number> (in reality it is some Double). I do this for the two list.
for (XYZPointModel xyz : pm.getTopoPoints()) {
topoPoints.getData().add(new Data<Number, Number>(xyz.getX(),xyz.getY()));
}
and then i compare the two list. I want to know if i have some data in dataList that i dont have in dataListSelected.
System.out.println(dataList.removeAll(dataListSelected));
I got a FALSE.
Here the containt of my 2 list :
3 : [Data[18.367963,-0.832832,null], Data[30.165189,-0.461874,null], Data[18.808959,-6.575699,null]]
3 : [Data[18.367963,-0.832832,null], Data[30.165189,-0.461874,null], Data[18.808959,-6.575699,null]]
Btw, i don't know why i have a double, double, null. I dont know where the null come from.
Why my removeAll don't work ?
I presume Data is actually JavaFX.XYChart.Data, which has another object node as per docs. Therefore, this is null. I do not know if the "toString" method prints the value of the node object, but it sure seems like it.
ArrayList (and many other collections) use the contains() (which uses equals() method) to determine whether to remove an object in the remove()/removeAll() methods. if you check the following condition:
dataList.get(0).equals(dataListSelected.get(0))
my guess is it would be false, and therefore removeAll fails as well.
1、ArrayList use equals() to remove,
if (o.equals(elementData[i]))
return i;
but XYChart.Data didn't override equals() method, so Data will use method of Object
public boolean equals(Object obj) {
return (this == obj);
}
2、XYChart.Data has three properties
X xValue, Y yValue, Object extraValue
double, double, null
I have a LinkedList of generic type State. In this LinkedList I have hundreds or even thousands of State objects. How can I, in the most efficient way to check if newly generated State object is already in the list?
State object:
public State(PlayerAddress player, LinkedList<BoxAddress> boxList, char[][] map, String solution, String stateHash) {
this.player = player;
this.boxList = boxList;
this.map = map;
this.solution = solution;
this.stateHash = stateHash;
boxListString = boxListToString(boxList);
mapString = mapString(map);
}
}
Additionally, State object consists of another generic objects as it is shown in the Constructor. How can I check if both State objects are the same in every aspect (PlayerAddress, LinkedList, etc.) ?
Have you tried the contains method? This could work. Also don't forget that you can overwrite stuff, so you could compare the hascodes as well by overwriting the hascode and compare methods.
In your case I would strongly suggest you will utilize the contains method. Which is the most efficient lookup for your case.
Looking at the java doc for contains:
public boolean contains(Object o)
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 (o==null ? e==null : o.equals(e)).
So you should only need to overwrite equals for your State class. The hashcode, will be required for sets.
My app downloading a Events from sqldatabase and add it to ArrayList<>. It do aduplicate so I wrote:
public static ArrayList<Events> list = new ArrayList<Events>();
static void addevhlp(Events e){
if (list.contains(e)){
Log.d("","it cointains")
}
else {
list.add(e);
}
}
But it never say me the list cointans element. What I'm doing wrong?
you have to override equals in Events, and define when two events are equals. The default implementation checks for equal object's reference. For instance, if your Events class has an int id field
#Override
public boolean equals(Object o) {
if (!(o instanceof Events)) {
return false;
}
Events event = (Events) o;
return id == event.id;
}
You should overrides equals and hashCode in your Events object.
See :
Best implementation for hashCode method for detail about hashCode
According to the documentation about ArrayList.contains:
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 (o==null ? e==null : o.equals(e)).
So, contains uses the equals implementation of your Events class to check if it holds the object.
if (list.contains(e))
If the events e has the same Reference than the one you have in the ArrayList the contains will work.
but If you want to check if the value is the same, but with a different Reference, you have to check if the properties of your events are exists or equals.
or you can simply use LINQ with List instead of ArrayList
C# how to determine, whether ArrayList contains object with certain attribute
I have to make an ArrayList that contains an object, the object has one int for year lets say 1
and I don't what another object with the same year 1.
If one object has the int = 1 , i dont want another object with that int(1) in my list.
i want to deny it.
Should I try using equal?
something like
#Override
public boolean equals(Object o){
Object object = (Object)o;
return this.getInt.equals(object.getInt());
}
Either use a Set...which explicitly disallows duplicates, or check if the list contains the element on insertion.
#Override
public boolean add(T element) {
if(contains(element)) {
return false;
} else {
return super.add(element);
}
}
Overriding equals wouldn't get you very far, as you'd be overriding it for the List itself (i.e. you'd be checking if two lists were equal).
Perhaps you can try using a HashMap linked that links that "int" with the object. That could be:
Map<Integer, Object> map = new HashMap<>();
map.put(object.getInt(), object);
...
//Each time you put a new object you could try this:
if(!map.contains(object.getInt()))
map.put(object.getInt, object);
//And you can retrieve your object by an int
int a = 1;
Object obj = map.get(1);
In this case, as the value is of type int, you can use equal operator.
public boolean equals(Object o){
Object object = (Object)o;
return (this.getInt()==object.getInt());
}
For this kind of requirement, ArrayList is not suggestible. As mentioned in the other answers try using HashMap.
Yes, you can. When you call
myArrayList.contains(myObejct);
the ArrayList will invode myObejct's equals method. So you can tell if the object is already in you list.
And I think you can change you method a little,
#Override
public boolean equals(Object o){
if (!(o instanceof YourClass))
return false;
YourClass object = (YourClass)o;
return this.getInt.equals(object.getInt());
}
because if you don't, the method "getInt" might cause a MethodNotFound exception.
Well, that is one way to approach the problem.
Your equals will probably work provided that you change Object object = (Object)o; to cast to the real class.
However, equals ought to cope with the case where o is not of the expected type. The contract requires you should return false rather than throwing a ClassCastException ...
You would then use list.contains(o) to test if an object with the same int value exists in the list. For example:
if (!list.contains(o)) {
list.add(o);
}
But when you override equals, it is best practice to also override hashcode ... so that your class continues to satisfy the equals / hashcode invariants. (If you neglect to do that, hash-based data structures will break for your class.)
However, this won't scale well, because the contains operation on an ArrayList has to test each element in the list, one at a time. As the list gets longer, the contains call takes longer ... in direct proportion; i.e. O(N) ... using Big O complexity notation.
So it may be better to use a Set implementation of some kind instead on ArrayList. Fepending on which set implementation you choose, you will get complexity of O(1) or O(logN). But the catch is that you will either have to to implement hashcode (for a HashSet or LinkedHashSet), or implement either Comparable or a Comparator (for a TreeSet).
Assume that I know that the list SomeList contains thatObj. Does the following code remove reference to thatObj from SomeList or not?
SomeClass el = (SomeClass) thatObj.clone();
SomeList.remove(el);
Can't find through the reference if this method compares objects somehow. Intuition suggests that it should use Object.equals which returns true if references point to the same object, hence this code will not work.
If not then an additional question: how to remove from list if don't have the reference but know all the members of the object in question?
Can't find through the reference if this method compares objects somehow. Intuition suggests that it should use Object.equals which returns true if references point to the same object, hence this code will not work.
Yes, you are right.
If not then an additional question: how to remove from list if don't have the reference but know all the members of the object in question?
Two possibilities:
override the equals method in your class, create a new instance with all known members and call remove passing the newly created instance as a parameter
iterate through all the objects inside the list and remove the one that has the members equal to the values you have
remove method internally uses the equals method to check for the object in the list. If equal returns true then it will be removed. Overriding the equals method will allow to remove the objects properly. For your reference here is the code of ArrayList remove method:
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
Override the equals method on the class - here is the javadoc. Also look at Overriding the java equals() method quirk and Overriding equals and hashCode in Java.
Search the list to find the member by returning the index, then get the object and remove it. You can also remove it by the index. The code
SomeList.indexOf()
could help you to get the index of the object that override equals() and hashCode().