CONTAINS METHOD IN ARRAYLIST PROBLEM.

J

justineee

if (!(dictionary.contains(getInputAdd)))
{
if (!(getInputAdd.equals("")))
{
word = new Word (getInputAdd);
dictionary.add(word);
inputAdd.setText("");
aCtr++;

if (aCtr==(inputConfigQty))
{
addButton.setEnabled(false);
inputFind.setEditable(true);
inputDelete.setEditable(true);
resetButton.setEnabled(true);
displayButton.setEnabled(true);
sortButton.setEnabled(true);
findButton.setEnabled(true);
deleteButton.setEnabled(true);
clearButton.setEnabled(true);
sortButton.setEnabled(true);
sortDecButton.setEnabled(true);
displayButton.setEnabled(true);
sortDecButton.setEnabled(true);
displayAllButton.setEnabled(true);
addDefButton.setEnabled(true);
delDefButton.setEnabled(true);
addDefOk.setEnabled(true);
delDefOk.setEnabled(true);
}
}
else
mBox.setText("Please put\na word.");
}
else if (dictionary.contains(getInputAdd))
mBox.setText(getInputAdd+" is already\nin the
dictionary.");
}

My program lets the user add words to store it like a customized
dictionary. However, he/she can't add the same words so I used the
contains method (dictionary is an ArrayList of a class I create Word,
ArrayList<Word>) to check if the dictionary already have the word. But
when I try it, the program still lets me add the same word so it
doubles up.

When I add 'a', it is in the dictionary. Then when I add 'a' again,
it's supposed to do this:

else if (dictionary.contains(getInputAdd))
mBox.setText(getInputAdd+" is already\nin the
dictionary.");

It doesn't work for me, it will still add 'a' many times. By the way,
getInputAdd is a String.

Help please. Thanks.
 
P

Patricia Shanahan

justineee wrote:
....
My program lets the user add words to store it like a customized
dictionary. However, he/she can't add the same words so I used the
contains method (dictionary is an ArrayList of a class I create Word,
ArrayList<Word>) to check if the dictionary already have the word. But
when I try it, the program still lets me add the same word so it
doubles up.
....

The key piece of code for debugging this is the equals(Object) method in
Word. The problem you describe is typical of a difference between which
Word instancess you consider to be equal, and which Word instances a
Word reports as being equal to itself.

Note that you should keep hashCode consistent with equals. That does not
affect ArrayList, but would matter if you later switched to using e.g. a
HashSet<Word>. See the Object API documentation for the rules about
equals and hashCode.

Patricia
 
O

Owen Jacobson

justineee wrote:

...> My program lets the user add words to store it like a customized

...

The key piece of code for debugging this is the equals(Object) method in
Word. The problem you describe is typical of a difference between which
Word instancess you consider to be equal, and which Word instances a
Word reports as being equal to itself.

There's a second issue hiding behind this. Because you add new Word
(getInputAdd) to the list, and not getInputAdd itself, the list will
never .contains(newInputAdd). If Word's equals method is correct, it
could .contains(new Word (getInputAdd)), at most.

-o
 
P

Patricia Shanahan

Owen said:
There's a second issue hiding behind this. Because you add new Word
(getInputAdd) to the list, and not getInputAdd itself, the list will
never .contains(newInputAdd). If Word's equals method is correct, it
could .contains(new Word (getInputAdd)), at most.

Good point, assuming getInputAdd is not of type word. Normally, objects
of different types should not be equal to each other.

There are exceptions. For example, java.util.List specifies a view of
equality that applies to all classes implementing List, and allows an
ArrayList to be equal to a LinkedList.

Patricia
 
L

Lew

if (!(dictionary.contains(getInputAdd)))
                 {
                  if (!(getInputAdd.equals("")))
                  {
                        word = new Word (getInputAdd);

Please, please, please soften your indentation. Four spaces maximum
per level is plenty.
 
L

Lew

Given your code:
if (!(dictionary.contains(getInputAdd)))
{
if (!(getInputAdd.equals("")))
{
word = new Word (getInputAdd);
dictionary.add(word);
etc.

You should have gotten a compiler error on the contains() call.
Didn't you?

The scope of 'word' should be narrower, i.e., within the
if ( ! getInputAdd.equals("") ) // extra parentheses omitted block.

She's telling you to override Word#equals().
There's a second issue hiding behind this. Because you add new Word
(getInputAdd) to the list, and not getInputAdd itself, the list will
never .contains(newInputAdd). If Word's equals method is correct, it
could .contains(new Word (getInputAdd)), at most.

This is why there should have been a compiler error. Did you not
declare 'dictionary' as a 'List<Word>'?

Really, 'dictionary' should be a 'Map <String, Word>' or similar
'Map', perhaps
'Map <String, List <String>>'.
 
B

Brian Odsgaard

justineee said:
if (!(dictionary.contains(getInputAdd)))
{
if (!(getInputAdd.equals("")))
{
word = new Word (getInputAdd);

You try to compare a String object with a Word object - they are not the
same. You have to create a Word object before comparing with the ArrayList
:

This method should do the trick:

public void addWord(String wordToAdd){
Word temp = new Word(wordToAdd);
if(!dictionary.contains(temp)){
dictionary.add(temp);
}
}

In this example you compare two Word objects

- Brian
 
J

justineee

You try to compare a String object with a Word object - they are not the
same. You have to create a Word object before comparing  with the ArrayList
:

This method should do the trick:

public void addWord(String wordToAdd){
Word temp = new Word(wordToAdd);
if(!dictionary.contains(temp)){
  dictionary.add(temp);

}
}

In this example you compare two Word objects

- Brian


I tried the method you did. Unfortunately, it didn't work. :|
However, I tried this.

if (jnd.getSource()==addButton){

getInputAdd = inputAdd.getText();
temp = new Word(getInputAdd);
if (!(dictionary.contains(temp)))
{
if (!(getInputAdd.equals("")))
{
word = new Word (getInputAdd);
dictionary.add(word);
inputAdd.setText("");
aCtr++;

temp is already a Word type. But it still didn't work.
 
B

Brian Odsgaard

I found the problem :)
The List contains references to the Word objects and not the object
themselves. When you create Word temp = new Word(aWord) - then you create a
new object with a new reference - the list don't contain this reference ...

This following example works for me - just add the methods to the Test
class:

public Test() {
dictionary = new ArrayList<Word>();
addWord("");
addWord("Test");
addWord("Word");
addWord("Test");
printWords();
}

public void addWord(String word) {
if (word != "") {
boolean found = false;
int i = 0;
while (i < dictionary.size() && !found) {//This runs until end of list or
a matching word is found
if (dictionary.get(i).getWord().equals(word)) {
found = true;
}
i++;
}
if (!found) {// This add the word to the dictionary - if it not exists
dictionary.add(new Word(word));
}
}
}

public void printWords() {
String s = "";
for (Word w : dictionary) {
s += w.getWord() + ", ";
}
System.out.println(s);
}

you might consider to use:
dictionary.get(i).getWord().equalsIgnoreCase(word)
this will make it case insensitive -> then Test equals test

- Brian
 
L

Lew

Brian said:
I found the problem :)
The List contains references to the Word objects and not the object
themselves. When you create Word temp = new Word(aWord) - then you
create a new object with a new reference - the list don't contain this
reference ...

The OP was already advised, more than once, to override Word#equals() and
apparently did not do so. Had they done so, then the List would evaluate
contains() in the way the OP intended, not by object identity but by value
equality.

justineee - override Word#equals().
getInputAdd = inputAdd.getText();
temp = new Word(getInputAdd);
if (!(dictionary.contains(temp)))
{
if (!(getInputAdd.equals("")))

It might be marginally more efficient to perform this test before the
contains() test.
{
word = new Word (getInputAdd);

Why in the world do you create yet another Word object on the same String?
dictionary.add(word);

dictionary.add( temp );
inputAdd.setText("");
aCtr++;

Brian said:
boolean found = false;
int i = 0;
while (i < dictionary.size() && !found) {
//This runs until end of list or a matching word is found
if (dictionary.get(i).getWord().equals(word)) {
found = true;
}

Simpler, clearer, and no slower to use 'dictionary.contains( word )'.

It also could be faster, depending on the Collection implementation used by
'dictionary'.

HashSet, for example, gives O(1) for 'contains()' but O(n) for iteration, and
has the virtue of eliminating duplicates automatically (thus obviating the
need even to do a 'contains()' check).
 
J

justineee

THANKS!! You guys are the best!

Brian, can I contact you directly if I ever had a problem again with
this one? Well, I got this from you. I'm just asking if ever..
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top