This question already has answers here:
String literal versus constants file in java
(3 answers)
Closed 6 months ago.
I'm newish to Java but having coded in similar languages before I feel I should know the answer to this but there are things in Java (e.g. generics) that are counterintuitive so hopefully someone can enlighten me in this case.
If I have a base class and two implementations with overrides to use a different string, is it more performant to define a class const for each sub class or is it just the same to directly return a string literal in the overridden method? Is a new string allocated for each instance in the "run" case below?
public abstract class OpBase {
protected abstract String getOpType();
public WriteOpType(){
Logger.info(getOpType());
}
public class WalkOperation extends OpBase {
protected String getOpType() {
return "walk";
}
}
or
public class RunOperation extends OpBase {
private static final String OP_TYPE_RUN = "run";
protected String getOpType() {
return OP_TYPE_RUN;
}
}
If you have String literals in your code, just like return "walk";, then these Strings will be internalized and handled just as if you had declared a 'constant' String.
So there is no difference performance-wise.
Also, this 'String variable' will always point to the exact same Object in memory, so even a == comparison on two results of that same function would yield true. (Except that you should never do == on strings, rather use string1.equals(string) for comparison)
This question already has answers here:
HashSet does not seem to realize that two objects are the same.
(3 answers)
Closed 2 years ago.
code
public class Society {
private String address;
private String name;
private Integer noOfFlats;
public Society(String address, String name, int noOfFlats) {
this.address = address;
this.name = name;
this.noOfFlats = noOfFlats;
}
public class SocietySet {
Set<Society> socSet = new HashSet<>();
public void addSocToset(Society society) {
socSet.add(society);
}
public void printSocSet() {
for (Society society : socSet) {
System.out.println("[ "+society.getName()+" ,"+society.getAddress()+"
,"+society.getNoOfFlats()+" ]");
}
}
Main Method
public static void main(String[] args) {
SocietySet societySet = new SocietySet(); // initialized object of class
Society society1 = new Society("pune","kamalapark",15);
Society society2 = new Society("pune","kamalapark",15);
Society society3 = new Society("pune","dsk",50);
societySet.addSocToset(society1);
societySet.addSocToset(society2);
societySet.addSocToset(society3);
societySet.printSocSet();
}
}
its printing same values of first two societies.
output :
[ kamalapark ,pune ,15 ]
[ kamalapark ,pune ,15 ]
[ dsk ,pune ,50 ]
where it should technically print unique values only,
what should be done to stop it from printing common values??
A Set by definition cannot contain two objects with 'equal' values.
Your problem is that your Society class does not have any particular concept of two Society objects being equal.
Society needs to define methods equal() and hashCode().
Add the below 2 methods to your Society class.You must first use the equals() and hashcode() methods to verify that the element is unique.
#Override
public boolean equals(Object obj) {
Society otherObj = (Society) obj;
return this.name.equals(otherObj .name) &&
this.noOfFlats.equals(otherObj .noOfFlats) &&
this.address.equals(otherObj .address) &&
this.hashCode() == otherObj .hashCode();
}
#Override
public int hashCode() {
return (43 + 777);
}
When you put an object into a Hashset it uses the object's hashcode value to determine where to put the object in the Set. But it also compares the object's hashcode to the hashcode of all the other objects in the Hash Set, and if there's no matching hashcode,the HashSet assumes that this new object is not a duplicate. HashSet finds a matching hashcode for two objects. one you're inserting and one already in the set-the HashSet will then call one of the object's equals() methods to see if these hashcode-matched objects really are equal. And if they're equal, the HashSet knows that the object you're attempting to add is a duplicate of something in the Set, so the add doesn't happen.
Override this equals method to check for equality of object along with hashcode.
public boolean equals(Object o)
You will need to override equals and hascode method.
#Override
public boolean equals(Object other) {
if(!other instanceof Society)
return false;
Society o = (Society)other;
return o.address.equals(address) && o.name.equals(name) && o.noOfFlats.equals(noOfFlats)
}
#Override
public int hashCode()
{
// your hascode implementation.
}
For detailed explaination: https://www.geeksforgeeks.org/override-equalsobject-hashcode-method/
I believe the root of your issue is not technical, but conceptual.
Your situation turns around the idea of Sets rejecting duplicates and it is true, Sets work exlusively with unique values. But the thing is that applies only to literals, that is single values individually defined by the user (things like "pune","kamalapark" and 15, when added to a set individually, as independent elements).
However, when, as in your code, a Set is made of objects, not literals, then to make it comply with uniqueness you should use hash and equal methods. In this thread we already have answers and comments covering this thing.
Hope my explanation makes your situation clearer.
This question already has answers here:
What issues should be considered when overriding equals and hashCode in Java?
(11 answers)
How to ensure hashCode() is consistent with equals()?
(8 answers)
Closed 3 years ago.
I know that I should implement hashCode() and equals(), however in reality I have no idea how to do it. I have a following class:
public class Dog {
private Integer id;
private Integer age;
private Instant dateOfBirth;
}
And now, I would like to be able to check if some list of dogs is subset of another list of dogs.
ArrayList<Dog>
Two dogs I consider as equals when they have the same age, id, dateOfBirth
Ofcourse, it seems to be easy to implement equals:
public boolean equals(Dog dog) {
return (dog.id == this.id && dog.age == dog.age && &this.dateOfBirth.equals(dog.dateOfBirth));
}
However, I have no idea how to implement hashCode to maintain equals-hashcode contract ?
This question already has answers here:
Is null check needed before calling instanceof?
(8 answers)
Closed 4 years ago.
I have written a simple equals() method for a class:
#Override
public boolean equals(Object obj) {
if(obj instanceof Cl) {
Cl u = (Cl)obj;
return u.i == i;
} else {
return false;
}
}
As I know, if I want compare if the class object equals to a null object, this returns false because of the instanceof, but according to my uni teacher this is a bad implementation, as the null check is missing. Can someone confirm for me if my theory is correct or not?
I think, a null check is not required and should not be there, because in this case there will not be any compile-time error or any exception if obj is null, because of the check if (obj instaceof C1).
This question already has answers here:
How to determine an object's class?
(13 answers)
Closed 6 years ago.
I need to write a new method that checks if certain values are of the type String or not.
I have two objects and I want to be able to check if these two objects are strings, if they are to then return true, and false otherwise.
I did start off with the following method:
public boolean stringTest()
{
boolean aString;
}
But could not get anything to work after that, any help would be greatly appreciated!
You can make use of instanceof and rewrite your method
public boolean stringTest(Object any)
{
return any instanceof String;
}
then
stringTest(townName); // true
stringTest(new Integer()); // false
Use instanceof:
public boolean isString(Object o) {
return o instanceof String;
}