I need to convert the method "contains()"
public boolean contains(List<Integer> list, int value){
for (int i : list) {
if(i == value)
return true;
into a method that can search for every datatype but i dont really know how to do it.
import java.util.List;
public class Search<T> {
public boolean contains(List<T> list, T value){
for ( T i : list) {
if(i == value)
return true;
}
return false;
}
}
This is my attempt so far but i dont know if this is all i have to do or not.
I hope someone can help me out.
There is already a method in List<T> that does that, List<T>::contains.
If you want to implement your own there are two ways to do it:
Same instance:
Here if the equals method hasn't been overridden it will return true if they are literally the same instance in memory.
public <T> boolean contains(List<T> list, T object){
for( T t : list){
if(t.equals(object))
return true;
}
return false;
}
Similar objects
Here you are forcing your T class to implement the Comparable interface, which contains a compareTo(o : Object) that returns 0 if they are similar.
public <T extends Comparable> boolean contains(List<T> list, T object){
for( T t : list){
if(t.compareTo(object) == 0)
return true;
}
return false;
}
Try equals instead of ==
import java.util.List;
public class Search<T> {
public boolean contains(List<T> list, T value){
for ( T i : list) {
if(i.equals(value))
return true;
}
return false;
}
}
Related
I am trying to achieve an util as this in Spring Boot:
public static boolean isAllEmptyOrNull(Collection... collectionList) {
for (Collection collection : collectionList) {
if (!Collections.isEmpty(collection)) {
return false;
}
}
return true;
}
so I can handle cases as:
isAllEmptyOrNull(listOfCat);
isAllEmptyOrNull(listOfDog, mapOfStringToString);
isAllEmptyOrNull(listOfDog, listOfCat);
isAllEmptyOrNull(listOfDog, listOfCat, mapOfStringToList, mapOfStringToMap);
Any help will be sincerely appreciated :)
Updated 2018-12-06
Thanks for the help of #Deadpool, my solution turns out:
public static boolean isAllCollectionEmptyOrNull(Collection... collections) {
for (Collection collection : collections) {
if (!Collections.isEmpty(collection)) {
return false;
}
}
return true;
}
public static boolean isAllMapEmptyOrNull(Map... maps) {
for (Map map : maps) {
if (!Collections.isEmpty(map)) {
return false;
}
}
return true;
}
Of course, you can use stream and method overloading as nullpointer does.
No. You cannot create it as generic as you are looking for since a Map is not a Collection.
And of course Collection... collectionList signifies var args for Collection type.
The only way would be to break them into two separate stubs as :
public static boolean isAllEmptyOrNull(Collection... collectionList) {
return Arrays.stream(collectionList).allMatch(Collection::isEmpty);
}
public static boolean isAllEmptyOrNull(Map... maps) {
return Arrays.stream(maps).allMatch(Map::isEmpty);
}
You can have two different util methods one for to check Collection objects and another one for Map objects, since Map is not child of Collection interface
public static boolean isAllEmptyOrNull(Collection... collectionList) {
return Arrays.stream(collectionList).anyMatch(item->item==null || item.isEmpty());
}
public static boolean isAllEmptyOrNull(Map... maps) {
return Arrays.stream(maps).anyMatch(item->item==null || item.isEmpty());
}
To check all objects null or empty
public static boolean isAllEmptyOrNull(Collection... collectionList) {
return Arrays.stream(collectionList).allMatch(item->item==null || item.isEmpty());
}
public static boolean isAllEmptyOrNull(Map... maps) {
return Arrays.stream(maps).allMatch(item->item==null || item.isEmpty());
}
You can try this:
public static boolean isAllEmptyOrNull(Collection... collectionList) {
return Arrays.stream(collectionList).anyMatch(Collection::isEmpty);
}
I'm trying to make a generic tuple class. It stores its elements as an ArrayList. Of course, this class should override hashcode and equals methods.
How could I make hashcode method for this class? You see, in the code, I am having trouble.
Also, for the equals method, why does the compiler force me to use the '?'. Why couldn't I just use the T?
public static class Tuple<T> {
ArrayList<T> tuple = new ArrayList<>();
public Tuple(ArrayList<T> items) {
for (T item : items) {
tuple.add(item);
}
}
#Override
public int hashCode() {
T sum = ???;
for (T item : tuple) {
sum += item.hashCode();
}
return sum;
}
#Override
public boolean equals(Object o) {
if (o instanceof Tuple<?>) {
Tuple<?> tup= (Tuple<?>) o;
if (tup.tuple.size() != this.tuple.size()) {
return false;
}
for (int i = 0; i < this.tuple.size(); i++) {
if (this.tuple.get(i) != tup.tuple.get(i)) {
return false;
}
}
return true;
} else {
return false;
}
}
}
As mentioned in the comments, we should delegate the hashCode and the equals methods to the ArrayList<T> tuple instance variable. For the hashCode it's trivial. For the equals it's just a little more complicated than that because we don't want our custom Tuple to be equals with an ArrayList. So here it is:
public class Tuple<T> {
// I made this private because I'm pedantric ;)
private final ArrayList<T> tuple = new ArrayList<>();
// this does the same as your code, it's just easier to read
public Tuple(ArrayList<T> items) {
tuple.addAll(items);
}
#Override
public int hashCode() {
return tuple.hashCode();
}
// generated by eclipse
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Tuple other = (Tuple) obj;
if (tuple == null) {
if (other.tuple != null)
return false;
} else if (!tuple.equals(other.tuple))
return false;
return true;
}
}
If you want to deal with the case when the tuple can be null, then you can use a slightly more complex hashCode:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((tuple == null) ? 0 : tuple.hashCode());
return tuple.hashCode();
}
In general, I don't like to write these methods myself. Usually, I make my IDE to generate the stuff. All I need to take care of is to re-generate it when I add new fields. Apache HashCodeBuilder and EqualsBuilder are also great alternatives.
I want to add an element after an element in the list if list already contain that element otherwise I want to add this new element to beginning
of the list.
Somehow below code is not working.
Any suggestions?
Does this approach correct performance wise?
public class HelloWorld
{
public static void main(String[] args) {
LinkedList<Task> l =new LinkedList<Task>();
l.add(new Task("a"));
l.add(new Task("b"));
l.add(new Task("c"));
int index;
if((index = l.lastIndexOf(new Task("a"))) != -1){
l.add(++index, new Task("5"));
}else{
l.addFirst(new Task("6"));
}
System.out.println(l);
}
}
class Task{
String value;
Task(String v){
value = v;
}
public boolean equals(Task t){
return t.value.equals(this.value);
}
public String toString(){
return this.value;
}
}
Output produces: [6,a,b,c]
Expected output: [a,5,b,c]
You are not overriding Object#equals in your Task class.
You need to parametrize it with Object, otherwise it's an overload.
That in turn doesn't allow your new Task("a") to be equal to new Task("a"), as Object.equals in invoked instead, and the references don't match.
This in turn will cripple your lastIndexOf invocation with unexpected results.
Example
#Override
public boolean equals(Object obj) {
// TODO your code, i.e. based on the "value" field
}
If you're using an IDE (which I recommend), you will have features allowing to draft equals (and hashCode) implementations based on your desired properties.
Your equals should look like that.
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Task task = (Task) o;
return value != null ? value.equals(task.value) : task.value == null;
}
I am new in Collection, as per my knowledge I have already override the hashCode() and Equals() method in Data class, but when I trying to search the element it is giving "not found". Why? Please look at the code below aand help me to find the bug.
import java.util.*;
public class WordCounter {
public static void main(String args[]) {
HashSet<Data> set=new HashSet<Data>();
set.add(new Data("this",2));
set.add(new Data("that",3));
set.add(new Data("which",6));
set.add(new Data("how",7));
System.out.println(new Data("how",7).hashCode());
set.add(new Data("hey",3));
set.add(new Data("me",5));
Iterator<Data> itr=set.iterator();
while(itr.hasNext()) {
Data d=itr.next();
d.display();
}
Data e=new Data("how",7);
System.out.println(e.hashCode()+"\t");
if(set.contains(e))
System.out.println("found");
else
System.out.println("not found");
}
}
Data Class:
class Data {
String word;
int fre;
public Data(String w,int f) {
word=w;
fre=f;
}
public void display() {
System.out.println(word+"\t"+fre);
}
public boolean equals(Data e) {
return this.word.equals(e.word) && this.fre == e.fre;
}
public int hashCode() {
return this.word.hashCode() + this.fre;
}
}
Perhaps your equals method is not used?
The signature is
public boolean equals(Object obj);
And it appears you have
public boolean equals(Data e);
Consider adding #Overrideannotations when you want to override a parent method (in this case java.lang.Object)
Update
Changing your method to this solves the case.
public boolean equals(Object d) {
Data e = (Data) d;
return this.word.equals(e.word) && this.fre == e.fre;
}
You equals() method is not used, because it has wrong signature. The correct signature is public boolean equals(Object o){ /* ... */ }. Because the signatures don't match, you are effectively overloading the method instead of overriding. The working equals() example:
#Override
public boolean equals(Object e)
{
if(!(e instanceof Data)){
return false;
}
Data d = (Data)e;
return this.word.equals(d.word) && this.fre == d.fre;
}
When overriding a method, use the #Override annotation - then the code fails to compile if the signatures don't match, thus:
#Override
public boolean equals(Data d){ ... }
Will give you an error and save some debugging time. Also check out this question.
I'd like my EqualTester generic class to call the overridden equals(...) method of its generic parameter, but it seems to call Object.equals instead. Here is my test code:
import junit.framework.TestCase;
public class EqualityInsideGenerics extends TestCase {
public static class EqualTester<V> {
public boolean check(V v1, V v2) {
return v1.equals(v2);
}
}
public static class K {
private int i;
private Object o;
public K(Object o, int i) {
this.o = o;
this.i = i;
}
public boolean equals(K k) {
return ((k.o != null && k.o.equals(o)) || o == null) && (k.i == i);
}
};
public void testEqual() {
K k1 = new K(null, 0);
K k2 = new K(null, 0);
assertTrue(k1.equals(k2)); // This one ok
EqualTester<K> tester = new EqualTester<K>();
assertTrue(tester.check(k1, k2)); // This one KO!
}
}
Could you please explain why this does not work, and how I could change my EqualTester class?
Is it because K does not actually override the Object.equals() method (because the parameter does not have the correct type)?
Thanks.
You need to code as public boolean equals(Object k), and then cast to k.
Right now you are just overloading the equals method.
It's also useful to add #Override annotation to the method.
When overriding the method signature must match exactly.
Because equals(K k) does not actually override the equals(Object o) method.
You must override equals(Object o) exactly in order for it to work.
Thanks Padmarag and Phill!
A solution that works:
#Override
public boolean equals(Object obj) {
if (!(obj instanceof K)) {
return false;
}
K k = (K)obj;
return ((k.o != null && k.o.equals(o)) || o == null) && (k.i == i);
}
Comments welcome: I started programming in Java only a few days ago...