0

When trying to identify if duplicates exist inside of the arrayList it doesn't seem to check, I am trying to override equals but the statement will just always pass as false and add the object to the list. In the action listener what is wrong with my statement?

The issue is in the action listener statement.

public class addTrackLayout extends JFrame{

private JTextField artist; 
private JTextField trackTitle;
private JTextField genre;
private JTextField duration;
private JTextField year;

private JLabel artistLabel;
private JLabel titleLabel;
private JLabel genreLabel;
private JLabel durationLabel;
private JLabel yearLabel;
private JLabel addLabel;

private String addArtist;
private String addTitle;
private String addGenre;
private double addDuration;
private int addYear;

private static final long serialVersionUID = 1L;

public addTrackLayout(String title){

    super (title);

    JPanel contentPane = new JPanel();
    contentPane.setLayout(new GridBagLayout());

    addLabel = new JLabel("Add Record");
    artistLabel = new JLabel("Artist Name:");
    titleLabel = new JLabel("Track Title:");
    genreLabel = new JLabel("Music Genre:");
    durationLabel = new JLabel("Duration:");
    yearLabel = new JLabel("Release Year:");

    artist = new JTextField(15);
    trackTitle = new JTextField(15);
    genre = new JTextField(15);
    duration = new JTextField(15);
    year = new JTextField(15);
    ArrayList<Music> music = TimelineLayout.music;

    JButton addButton = new JButton("Add");
    addButton.setActionCommand("add");


        //Actions for buttons.
        addButton.addActionListener(new ActionListener(){

                public void actionPerformed(ActionEvent e){

                    addArtist = artist.getText();
                    addTitle = trackTitle.getText();
                    addGenre = genre.getText();
                    addDuration = Double.parseDouble(duration.getText());
                    addYear = Integer.parseInt(year.getText());

                    Music m = new Music(addArtist, addTitle, addGenre, addDuration, addYear);


                    if(music.contains(m)){

                        JOptionPane.showMessageDialog(null, "already exists");
                    }
                    else{

                        music.add(m);       
                        JOptionPane.showMessageDialog(null,"added to db");
                    }

                }   

            });

Music Class:

public class Music {

private String artist;
private String title;
private String genre;
private double duration;
private int year;


public Music(String initArtist, String initTitle, String initGenre, double initDuration, int initYear)
{   
    artist =  initArtist;
    title= initTitle;
    genre = initGenre;
    duration = initDuration;
    year = initYear;
}

public String getArtist() {
    return artist;
}

public void setArtist(String artist) {
    this.artist = artist;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public double getDuration() {
    return duration;
}

public void setDuration(double duration) {
    this.duration = duration;
}

public int getYear() {
    return year;
}

public void setYear(int year) {
    this.year = year;
}

public String getGenre() {
    return genre;
}

public void setGenre(String genre) {
    this.genre = genre;
}

Override and hash.

public boolean equals(Object obj)   {

 if (this == obj) 
 {
     return true;
 }

 else if (obj == null)
 {
     return false;              
 }

 else if (obj instanceof Music) 
 {
     Music music = (Music) obj;

     if (music.getArtist().equals(this.getArtist()) && (music.getTitle().equals(this.getTitle())))       
        {
            return true;
        }
     }
        return false;
    }

@Override
public int hashCode()
{
    int hash = 7;
    hash = 31 * hash + Objects.hashCode(this.getArtist());
    hash = 31 * hash + Objects.hashCode(this.getTitle());
    return hash;
}

2 Answers2

0

The problem is that you need to understand object equality in Java, as well as how it is implemented in ArrayList.

The method list.contains(obj):

at least one element e such that (o==null ? e==null : o.equals(e)).

(from https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#contains(java.lang.Object))

This means that the array list is running Music.equals(...)

I can only assume that you did not override .equals in your Music object to ensure that objects could be compared.

Quick refresher:

obj == obj

checks if the objects point to the same thing. So...

Music m;
Music m2;
m == m2; //would be false, they're seperate.
m.equals(m2) //you should implement this so it is true.

You said you wanted to see if an element already exists in the array.

This is done by implementing equals(Object o) in the Music class.

@override
public boolean equals(Object o){
     boolean equals = true;
     if(o instanceof Music){
        //here, we need to compare all the fields in music
        //repeat for title, genre, duration, year, etc.

        if(!(Music) o.artist.equals( this.artist){
             equals = false;
        }
    }
    return equals;
}

Further reading:

  1. Compare two objects with .equals() and == operator - Take special attention to the answer marked as accepted, if you're gonna compare instances of a custom class you will need to override the equals() method and, consequently, the hashCode() method.

  2. https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html - all the methods for ArrayList - to really learn the datastructure, you should essentially memorize this.

d0ge
  • 26
  • 5
  • I understand the difference between the equals outcomes, I just can't get my head around trying to compare the one instance (in my case 'm') to all the instances inside the array. I understand if I override in my Object class and create 2 instances like you said above and use the equals method. But how do I implement the 'm.equals(array of Instances)' ?? – JHargreaves Nov 22 '17 at 19:55
  • My comment was more generic than meant to be taken specifically; What I meant was that using Array.contains, that method does the work of comparing all the instances. HOW it does it, is the Music.equals in method (calling `list.contains(ourMusic)` will do a loop over every element, and compare `ThatElement.equals(ourMusic)`. Thus, that is what you have to override and implement. – d0ge Nov 22 '17 at 19:57
  • Please take a look at my revised example of the equal methods to understand what I mean about comparing instances of Music. ArrayList.contains will call Music.equals – d0ge Nov 22 '17 at 20:05
  • I've done my research on what you've said, I understand the override equals benefits, but I still don't understand how in my action I can check if its inside the array, I feel like I am doing everything right, but it doesn't work... I'll update my code to show my Override – JHargreaves Nov 23 '17 at 17:06
  • Try testing seperately in a different main method to prove to yourself it works: `public static void main(String[] args){ Music m = new Music(addArtist, addTitle, addGenre, addDuration, addYear); Music m2 = new Music(addArtist, addTitle, addGenre, addDuration, addYear); ArrayList q = new ArrayList – d0ge Nov 23 '17 at 18:23
0

You have to override the hashcode and equals method in your Music class and implement the comparable interface. And when you're adding new music to your music list check to see if your music list contains it, if not add it.

tmj010
  • 34
  • 3
  • Can you check to see if I am on the right lines with my override methods, because I still can't get it compare the objects. – JHargreaves Nov 23 '17 at 17:26
  • In your equals method, first check to see if the obj is not an instanceof music and if it's not return false. If it is, cast it to music and compare each property that make a music equal – tmj010 Nov 23 '17 at 17:46