How to remove duplicates in the Java HashSet - java

I have a set of this structure. How to remove duplicates of equal object of that class? Equals means field File plik is the same.
EDIT:
But the problem gut bigger I don't have duplicates but I would like to replace old SET member by new.
Withoud 3rd party libraries.
import java.io.*;
public class WordInfo implements Serializable {
File plik;
Integer wystapienia;
public WordInfo(File plik, Integer wystapienia) {
this.plik = plik;
this.wystapienia = wystapienia;
}
public String toString() {
// if (plik.getAbsolutePath().contains("src") && wystapienia != 0)
return plik.getAbsolutePath() + "\tWYSTAPIEN " + wystapienia;
// return "";
}
}
EDIT
I don't have this HashCodeBuilder I want to use Java standard libraries
public int hashCode() {
return new HashCodeBuilder(17, 31).append(plik).append(wystapienia).toHashCode();
}
public boolean equals(Object obj) {
File f = (File) obj;
return(plik.getAbsoluteFile().equals(f.getAbsolutePath()));
}

As discussed here, override equals.
public class Person {
private String name;
private int age;
// ...
public int hashCode() {
return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
// if deriving: appendSuper(super.hashCode()).
append(name).
append(age).
toHashCode();
}
public boolean equals(Object obj) {
if (obj == null)
return false;
if (obj == this)
return true;
if (obj.getClass() != getClass())
return false;
Person rhs = (Person) obj;
return new EqualsBuilder().
// if deriving: appendSuper(super.equals(obj)).
append(name, rhs.name).
append(age, rhs.age).
isEquals();
}
}

public class WordInfo implements Serializable {
File plik;
Considering that following is how you can override the equals and hashCode method as per your requirement:
#Override
public boolean equals(Object obj) {
if(this == obj) return true;
if(!(obj instanceof WordInfo)) return false;
return this.plik.equals(((WordInfo) obj).plik);
}
#Override
public int hashCode() {
return this.plik.hashCode();
}

Related

When trying to overwrite a equals method in Java, it won't compare the values only the object itself?

In this exercise, I need to create a equals() method for a Drink class. Two drinks are the same if they have the same name and same size. I am receiving false from testing the method, even though I'm certain it should be true.
The main code:
public class Drink {
private String name;
private double size;
public Drink(String name, double size)
{
this.name = name;
this.size = size;
}
public String getName()
{
return name;
}
public double getSize()
{
return size;
}
//I tried to stringify the double values
public boolean equals(Drink a, Drink b){
String q = String.valueOf(a.getSize());
String w = String.valueOf(b.getSize());
if(q.equals(w) && a.getName().equals(b.getName())){
return true;
}
else{
return false;
}
}
}
The tester Code:
public class DrinkTester
{
public static void main(String[] args)
{
Drink one = new Drink("Soda", 12);
Drink two = new Drink("Soda", 12);
Drink three = new Drink("Soda", 20);
System.out.println(one.equals(two));
System.out.println(one.equals(three));
}
}
You need to override the equals method, if you use the
#Override annotation you'll see if you're doing it right.
public boolean equals(Object obj) {
return (this == obj);
}
That is the Object one, so yours might for example look like:
#Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Drink drink = (Drink) obj;
return this.size.equals(drink.size)
&& this.name.equals(drink.name);
}
you'll also have to override your hashCode if you want your code to work optimally.
(And i've only recently noticed that if you use Objects.hash in your overridden hashCode method, your overridden equals method won't get used, the Objects one will get used instead)

Abstract Class Java

I need to write abstract class, which looks like this.
public abstract class Value {
public abstract String toString();
public abstract Value add(Value v);
public abstract Value sub(Value v);
public abstract boolean eq(Value v);
public abstract boolean lte(Value v);
public abstract boolean gte(Value v);
public abstract boolean neq(Value v);
public abstract boolean equals(Object other);
public abstract int hashCode();
public abstract Value create(String s);
}
Now I need to make few classe, which inherit from that one. I started from Int class and implemented it like this:
public class Int extends Value {
int val;
public String toString() {
String toStr = Integer.toString(val);
return toStr;
}
public Int add(Value v) {
Int result = new Int();
if(v instanceof Int) {
Int temp = (Int) v;
result.val = val + temp.val;
}
return result;
}
public Int sub(Value v) {
Int result = new Int();
if(v instanceof Int) {
Int temp = (Int) v;
result.val = val - temp.val;
}
return result;
}
public boolean eq(Value o) {
if(this == o) return true;
if(this == null) return false;
if(getClass() != o.getClass()) return false;
Int other = (Int) o;
return toString() == other.toString();
}
public boolean lte(Value v) {
if(v instanceof Int) {
Int temp = (Int) v;
return this.val < temp.val;
}
return false;
}
public boolean gte(Value v) {
if(v instanceof Int) {
Int temp = (Int) v;
return this.val > temp.val;
}
return false;
}
public boolean neq(Value v) {
if(v instanceof Int) {
Int temp = (Int) v;
return !eq(temp);
}
return true;
}
public boolean equals(Object o) {
if(this == o) return true;
if(this == null) return false;
if(getClass() != o.getClass()) return false;
Int other = (Int) o;
return toString() == other.toString();
}
public int hashCode() {
Integer hash = val;
return hash.hashCode();
}
public Int create(String s) {
val = Integer.parseInt(s);
return this;
}
}
Everything is compiling and working, but I have no clue if my hashcode() function and equals() are good. Furthermore i want to use create() to make objects like this:
getInstance().create("1234");
Is my method also sufficient?
Everything is compiling and working, but I have no clue if my hashcode() function and equals() are good.
Your equals() should compare int val and not result of toString() of compared objects (this.val == other.val).
Your hashCode() looks good, though I would add #Override to it (same with equals()).
Furthermore i want to use create() to make objects like this: getInstance().create("1234");
Looking at its implementation, it looks fine (i.e. would work according to your needs):
public Int create(String s) {
val = Integer.parseInt(s);
return this;
}
though I don't think you really want to use it with getInstance(). Simply Int.create() would be enough:
public static Int create(String s) {
val = Integer.parseInt(s);
return new Int(val);
}
Note that you would need a private constructor.
Also, as someone noted in the comments, consider using generics instead of inheritance.
The hashCode() method is fine (although I'd add an #Override annotation, just to make the code easier to maintain and avoid mistakes), but the equals(Object) definitely isn't.
Following the logic you have in place, == isn't the right way to compare strings. You should use equals instead (see, e.g., How do I compare strings in Java?). In addition, as Joakim Danielson noted in the comments, this can never be null - you should check if o is null instead:
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null) {
return false;
}
if(getClass() != o.getClass()) {
return false;
}
Int other = (Int) o;
return toString().equals(other.toString()); // Here!
}
But in all fairness, there's no reason to use toString - you could just compare the internal val:
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null) {
return false;
}
if(getClass() != o.getClass()) {
return false;
}
Int other = (Int) o;
return val == other.val; // Here!
}
First when you override Methods please do it with #Override Annotation. Then i would implement your equals method in another way. Just do return this.val == other.val instead of doing this.toString() == other.toString(). Your toString() method implementation is ok. Your hashCode is good as well. But please remove that create method. Use a constructor instead.
Can I implement equals() method using eq() like this ?
public boolean equals(Object o) {
Value compare = (Value) o;
return eq(compare);
}

How to make custom Tuple class generic?

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.

my deterministic turing machine won't work, because my equals and indexof method throw no source error

I have the problem, that my equals method doesnt work as i want it to. I want to implement a deterministic turing machine, so I want to add the method findCommand(), which searchs through a arraylist of commands. So I decided to create a searchDummy to find all Transitions that are available for the Configuration I have.
Class States:
public class States {
private int stateId;
private boolean rejState;
private boolean accState;
private boolean stopState;
private List<Commands> commands = new ArrayList<Commands>();
equals in class States:
#Override
public boolean equals(Object other) {
if (this == other) {
return true;
} else if (other instanceof States) {
States otherState = (States) other;
return (stateId == otherState.stateId);
} else {
return false;
}
}
hashCode:
#Override public int hashCode() {
StringBuilder b = new StringBuilder(stateId);
return b.toString().hashCode();
}
this is the findCommand method in States:
public Commands findCommand(States state, char inputTapeChar,
char[] tapeChars) {
Commands searchDummy = new Commands(state, inputTapeChar, tapeChars,
null, null, null, null);
int pos = commands.indexOf(searchDummy);
return pos >= 0 ? commands.get(pos) : null;
}
commands is my arraylist, so I want to find the searchDummy with indexOf().
I have the class Commands, which holds the attribute Configuration configuration, the class Configuration, which holds the attributes of a Configuration and the attribute Transition transition and the class transition that holds the attributes for itself.
Class Commands:
public class Commands implements Comparable<Commands> {
private Configuration configuration;
Class Configuration:
public class Configuration {
private Transition transition;
private States state;
private char inputTapeChar;
private char[] tapeChars;
Class Transition:
public class Transition {
private States targetState;
private Direction inputTapeHeadMove;
private char[] newTapeChars;
private Direction[] tapeHeadMoves;
i have this equals method in Commands:
#Override public boolean equals(Object other) {
if (this == other) {
return true;
} else if (other instanceof Commands) {
Commands otherCmd = (Commands) other;
return (configuration.equals(otherCmd.configuration));
} else {
return false;
}
}
and this hashcode
#Override
public int hashCode() {
StringBuilder b = new StringBuilder(configuration.getState() + ","
+ configuration.getInputTapeChar());
for (char c : configuration.getTapeChars()) {
b.append("," + c);
}
return b.toString().hashCode();
}
then almost the same in Configuration:
#Override
public boolean equals(Object other) {
if (this == other) {
return true;
} else if (other instanceof Configuration) {
Configuration otherConfi = (Configuration) other;
return (state.equals(otherConfi.state))
&& (inputTapeChar == otherConfi.inputTapeChar)
&& (Arrays.equals(tapeChars, otherConfi.tapeChars));
} else {
return false;
}
}
hashcode:
#Override
public int hashCode() {
StringBuilder b = new StringBuilder(state + "," + inputTapeChar);
for (char c : tapeChars) {
b.append("," + c);
}
return b.toString().hashCode();
}
equales in class State:
#Override
public boolean equals(Object other) {
if (this == other) {
return true;
} else if (other instanceof States) {
States otherState = (States) other;
return (stateId == otherState.stateId);
} else {
return false;
}
}
so my question:
when I debug this it goes through until it's finished with the checks but when it should return the value it stucks at Configuration.equals(...) and shows the error no source found!
what is the problem? Are the hashcodes wrong? Or are the equals wrong?
I never used equals before so I dont know when i need to use it or how i need to fix this. thanks for your help.
Your hashCode implementation looks suspect - all that String stuff is not standard.
For example for your Transition class should be something like this:
#Override
public int hashCode() {
int result = 17;
result = 31 * result + targetState.hashCode();
result = 31 * result + inputTapeHeadMove.hashCode();
result = 31 * result + newTapeChars.hashCode();
result = 31 * tapeHeadMoves.hashCode();
return result;
}
Most IDEs will offer autogen of hashCode and equals methods.

java check if list of object contains object with concrete name

I have list of objects:
List<City> cities = city.getList();
I would like to remove duplicates (where duplicates mean objects with the same value of parameter name and different (id, and other parameters);
I have code for that:
for(City c: cities) {
System.out.println("analise " + c.name);
if(!temp.contains(c)) {
temp.add(c);
}
}
I've wrote for that hashCode() and equals() method:
#Override
public int hashCode() {
return id.hashCode();
}
...
#Override
public boolean equals(Object other) {
if (other == null) return false;
if (other == this) return true;
if (!(other instanceof GenericDictionary))return false;
GenericDictionary otherMyClass = (GenericDictionary) other;
if(this.name == otherMyClass.name) {
return true;
} else {
return false;
}
}
But it dosnt apply it. It use object.equals() method instead of mine
It looks like your problem is in String comparison :
if(this.name == otherMyClass.name)
Change it to :
if(this.name.equals(otherMyClass.name))

Categories