I want to make a phone book.
Executing and putting two identical objects is not recognized in the "while" loop with the method "contains(OBJECT)==TRUE".
Where did my code go wrong? Appreciate any help thanks!
Main
public class MainRubrica {
public static void main(String[] args) {
Scanner keyb= new Scanner(System.in);
System.out.print("Inserire il numero di contatti da aggiungere: ");
int nM= keyb.nextInt();
Vector<Contatto> rubrica = new Vector<Contatto>(20, 5);
for(int i=0;i<nM;i++){
System.out.println("\nContatto n."+(i+1));
Contatto c =new Contatto();
c.inserimento();
while(rubrica.contains(c)==true) {
System.out.println("Il contatto è già presente");
c.inserimento();
}
rubrica.addElement(c);
}
for(int i=0;i<nM;i++){
System.out.println("\nContatto n."+(i+1));
System.out.println(rubrica.elementAt(i));
}
Class Contatto
public class Contatto {
//attributi
private String nome;
private String cognome;
private String numeroTel;
//costruttore di default
public Contatto(){
nome="";
cognome="";
numeroTel=""; }
//costruttore con parametri
public Contatto(String nome, String cognome, String numeroTel){
this.nome=nome;
this.cognome=cognome;
this.numeroTel=numeroTel; }
//metodo set
public void setNome(String nome){
this.nome=nome; }
public void setCognome(String congnome){
this.cognome=cognome; }
public void setNumeroTel(String numeroTel){
this.numeroTel=numeroTel; }
//metodo get
public String getNome(){
return nome; }
public String getCognome(){
return cognome; }
public String getNumeroTel(){
return numeroTel; }
//metodo inserimentoContatto
public void inserimento(){
Scanner keyb= new Scanner(System.in);
System.out.println("Nome: ");
nome=keyb.nextLine();
System.out.println("Cognome: ");
cognome=keyb.nextLine();
System.out.println("Numero di telefono: ");
numeroTel=keyb.nextLine();
}
public String toString(){
return "Nome: "+nome+"\nCognome: "+cognome+"\nNumero di Telefono: "+numeroTel;
}
}
I don't understand what you are trying to accomplish, but the reason you aren't ever getting into the while loop is that you haven't overridden the Object.equals method for your Contatto class. Here is the definition of Object.equals:
public boolean equals(Object obj) {
return (this == obj);
}
Using this definition of the "equals" method, it doesn't matter whether all the fields have equivalent values. The two objects are not equal unless they are the same object.
Overriding the equals method in your Contatto class will address this. When you do that, you also need to override the Object.hashCode method so as to maintain the contract for that method as well (equal objects must have equal hash codes). I like to use the Apache Commons Lang library for this. Using that library, you would add something like these methods to your Contatto class:
#Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
} else if (obj instanceof Contatto) {
final Contatto rhs = (Contatto) obj;
return new EqualsBuilder().append(getNome(), rhs.getNome())
.append(getCognome(), rhs.getCognome())
.append(getNumeroTel(), rhs.getNumeroTel())
.isEquals();
} else {
return false;
}
}
#Override
public int hashCode() {
return new HashCodeBuilder().append(getNome()).append(getCognome())
.append(getNumeroTel()).toHashCode();
}
Without the Apache Commons Lang library (should be equivalent to what the library is doing):
#Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
} else if (obj instanceof Contatto) {
final Contatto rhs = (Contatto) obj;
return Objects.equals(getNome(), rhs.getNome())
&& Objects.equals(getCognome(), rhs.getCognome())
&& Objects.equals(getNumeroTel(), rhs.getNumeroTel());
} else {
return false;
}
}
#Override
public int hashCode() {
int hash = 17 * 37 + getNome().hashCode();
hash = hash * 37 + getCognome().hashCode();
hash = hash * 37 + getNumeroTel().hashCode();
return hash;
}
After you add those methods, or implementations of them that match your definition of equality between two Contatto instances, then you should see your code entering that while loop if you input equivalent Contatto objects.
Related
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)
Here is my application
public class testwithmain {
public static void main(String[]args)
{
Money m12CHF = new Money(12,"CHF");
System.out.println(m12CHF.amount());
Money m14CHF = new Money(14,"CHF");
System.out.println(m14CHF.amount());
Money expected = new Money(26,"CHF");
System.out.println("expected "+expected.amount()+expected.currency());
Money result = m12CHF.add(m14CHF);
System.out.println("result "+result.amount()+result.currency());
System.out.println(expected.equals(result));
}
}
//-------------------------
public class Money {
private int fAmount;
private String fCurrency;
public Money(int amount, String currency) {
fAmount = amount;
fCurrency = currency;
}
public int amount() {return fAmount;}
public String currency() {return fCurrency;}
public Money add(Money m) {
return new Money(amount() + m.amount(), currency());
}
}
The result is:
12
14
expected 26CHF
result 26CHF
false
Please, why i have false ?
Thank you so much.
Your Money class lacks an implementation of equals method, which is required in order for Java to know that the object representing the result of m12CHF.add(m14CHF) and the new Money(26,"CHF") represent the same thing, even though the two are distinct Java objects.
The code inside equals should follow this general template:
#Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof Money)) {
return false;
}
Money other = (Money) o;
... // Your code goes here
}
#Override
public int hashCode() {
return Objects.hash(fAmount, fCurrency);
}
Your implementation needs to compare fAmount and fCurrency of your object to the values in other.fAmount and other.fCurrency. Use equals for comparison of String objects; numbers can be compared with == operators.
As Nexevis said you need to override the equals method (which is inherited from the object class)
#Override
public boolean equals(Object obj){
if(obj instanceof Money){
Money other = (Money)obj;
//now you define when two intance object of Money are equal...
}
//...
}
Why is this necessary?
Because the current equals that you are using it is the equals from the Object class. Object's equals method defines that two objects are the same when they have the same reference
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.
heres my code for a library application
package com.accenture.totalbeginner;
public class Person {
private String name;
private int maximumbooks;
public Person() {
name = "unknown name";
maximumbooks = 3;
}
public String getName() {
return name;
}
public void setName(String anyname) {
name = anyname;
}
public int getMaximumbooks() {
return maximumbooks;
}
public void setMaximumbooks(int maximumbooks) {
this.maximumbooks = maximumbooks;
}
public String toString() {
return this.getName() + " (" + this.getMaximumbooks() + " books)";
}
public boolean equals(Person p1) {
if(!this.getName().equals(p1.getName())) {
return false;
}
if(!this.getMaximumbooks().equals(p1.getMaximumbooks())) {
return false;
}
return true;
}
}
(!this.getMaximumbooks().equals(p1.getMaximumbooks()))
this is saying cannot invoke .equals on primitive type(int)
I know what that means, but I have tried everything and I can't think how to correct it.
If you need any of the code from other classes let me know.
equals() is used for Objects (String, Integer, etc...)
For primitives like int, boolean, char etc, you have to use ==
getMaximumbooks() returns a primitive type int not an Object. You have to compare it with == or in you case != (not equals)
if (this.getMaximumbooks() != p1.getMaximumbooks())
{
return false;
}
return true;
Just use == if you're comparing primitives.
Also, try not to use getters when working into the class because you have already access to all the fields (private or not).
public boolean equals(Person p1)
{
return this.maximumBooks == p1.getMaximumBooks();
}
Cannot invoke equals(int) on the primitive type int
.equals() is a method which is used only in objects
for int , double just as in the picture I have attached, use (==)
e.g (int a == int b)
I'm trying to figure out why i keep getting the error that my AM class does not override abstract method. In my teachers UML diagram it only shows that i need the equals (Object o) method in my parent radio class. Also i'm not declaring it as abstract in my abstract class.
public abstract class Radio implements Comparable
{
double currentStation;
RadioSelectionBar radioSelectionBar;
public Radio()
{
this.currentStation = getMin_Station();
}
public abstract double getMax_Station();
public abstract double getMin_Station();
public abstract double getIncrement();
public void up()
{
}
public void down()
{
}
public double getCurrentStaion()
{
return this.currentStation;
}
public void setCurrentStation(double freq)
{
this.currentStation = freq;
}
public void setStation(int buttonNumber, double station)
{
}
public double getStation(int buttonNumber)
{
return 0.0;
}
public String toString()
{
String message = ("" + currentStation);
return message;
}
public boolean equals (Object o)
{
if (o == null)
return false;
if (! (o instanceof Radio))
return false;
Radio other = (Radio) o;
return this.currentStation == other.currentStation;
}
public static void main(String[] args)
{
Radio amRadio = new AMRadio();
System.out.println(amRadio);
Radio fmRadio = new FMRadio();
System.out.println(fmRadio);
Radio xmRadio = new XMRadio();
System.out.println(xmRadio);
}
}
public class AMRadio extends Radio
{
private static final double Max_Station = 1605;
private static final double Min_Station = 535;
private static final double Increment = 10;
public AMRadio()
{
currentStation = Min_Station;
}
public double getMax_Station()
{
return this.Max_Station;
}
public double getMin_Station()
{
return this.Min_Station;
}
public double getIncrement()
{
return this.Increment;
}
public String toString()
{
String message = ("AM " + this.currentStation);
return message;
}
}
You have to implement the compareTo() method, given that Radio implements the Comparable interface and a concrete implementation for this method wasn't provided in the Radio class, so you have two choices:
Implement compareTo() in all of Radio's subclasses
Or implement compareTo() in Radio
Something like this, in AMRadio:
public int compareTo(AMRadio o) {
// return the appropriate value, read the linked documentation
}
Or like this, in Radio:
public int compareTo(Radio o) {
// return the appropriate value, read the linked documentation
}