-1

I'm new to OO. I've just started programming in Java for my university course.

I have a problem: I have a method within the Club class to search for a member's name (or part of a name, according to my worksheet. I have a class that tests this without me having to manually create objects from the Club class (I'm using BlueJ).

Here's the search method:

public void searchMember(String name){
    i=0;
    found = false;

    while( i < members.size() && !found ){
        if(members.contains( name )){
            found = true;
        }else{
            i++;
        }
    }

    if(found == true){
        System.out.println(members.get(i));
    }else{
        System.out.println("Och Naw ... Member not found.");
    }
}

And here is the testing class code:

public void demo()
{
    club = new Club();
    club.join(new Membership("Gordy Broon", 1, 1972));
    club.join(new Membership("Eck Salmon", 9, 1965));
    club.join(new Membership("Davie Caramel", 5, 1960));

   System.out.println("Now doing some searching: ");
   club.searchMember( "mon" );
   System.out.println(" ");

   System.out.println("And some more searching: ");
   club.searchMember("moon");
   System.out.println(" ");
}

Can someone explain to me why when searching for "mon" the result is not found?

To my understanding this should work.

I am new so ANY help and explanation would be amazing ^_^ Thanks!

neonite
  • 5
  • 9
  • Can you show me all your class code please. Just to see what is members. Also do you know what are iterators (just fto write you a proper answer) – Luis Alves Nov 21 '14 at 21:38
  • In your loop you are invoking `if(members.contains( name )){` and based on it you are either incrementing `i` or setting `found` to true, but I don't see how `members.contains` is using `i`. Maybe you need to add something like `members.get(i).contains(name)`? – Pshemo Nov 21 '14 at 21:39
  • members is a field at the top of the Club class. ArrayList members; – neonite Nov 21 '14 at 21:41
  • Also code like `if(found == true)` is considered as bad practice because it is very easy to make mistake like `if(found = true)` where instead of comparing (`==`) you are assigning (`=`) `true` to `found` variable. So instead of `if(found == true)` simply use `if(found)` or instead of `if(found != true)` or `if(found==false)` use `if(!found)`. – Pshemo Nov 21 '14 at 21:41
  • @Pshemo yeah, I tried that but an error occurs: cannot find symbol - method members(int) – neonite Nov 21 '14 at 21:44
  • Yeah, you're right on the bad practise thing. Will work on it :) – neonite Nov 21 '14 at 21:45
  • It is not `members(int)` but `members.get(i)`. This method will return element stored at position `i`. Since returned element would be probably instance of `Membership` you will also need to use method which will return name of person like `members.get(i).getName().contains(searchedName)`. – Pshemo Nov 21 '14 at 21:45
  • Anyway my comments are only guesses. If you want to get real answer we would need to see some code which would let us reproduce your problem, so consider [edit]ting your question. – Pshemo Nov 21 '14 at 21:50
  • Okay I'll supply Pastebin links. Membership Class: [link](http://pastebin.com/pJpRAYDL) Club Class: [link](http://pastebin.com/rqsWgTGK) Testing Class: [link](http://pastebin.com/EzV3rhsj) – neonite Nov 21 '14 at 22:05
  • @JarrodRoberson While I agree with tag removal edit I don't see it as duplicate since OP is not trying to compare strings with `==` instead of `equals`. In fact OP is using `contains` which seems like correct choice. – Pshemo Nov 21 '14 at 22:05
  • I believe I'm expected to use .contains But to my understanding, I feel like .contains compares Strings only (or am I misunderstanding?) – neonite Nov 21 '14 at 22:09
  • 1
    There are two different `contains`: The one on Collection (including lists) finds matching (identical) objects; the one on String finds matching substrings. – David Conrad Nov 21 '14 at 22:11
  • @JarrodRoberson This question IS NOT a duplicate of that one. This has to do with using Collection.contains to try to find an object that is not a String, but is "known by" a string (has a name); that question is about confusing `==` with `equals`. – David Conrad Nov 21 '14 at 22:12
  • Thanks everyone for their help :) – neonite Nov 21 '14 at 22:15
  • Can someone explain why this question has been -1'd? – neonite Nov 21 '14 at 22:16
  • "*Can someone explain why this question has been -1'd?*" I suspect that because your question wasn't clear (you didn't provide at start enough informations about your code which would let us reproduce your problem, which means we had to guess what could go wrong which is rarely effective way of solving problems). Also instead of [edit]ing your question with [SSCCE](http://sscce.org/). So you did 3 things to make helping you harder: 1 you posted your full code (instead of SSCCE); 2 as a link (instead of code); 3 in comments (instead of your writing it in question). – Pshemo Nov 22 '14 at 05:09
  • Ohhh sorry, im new haha. Will do better next time :) – neonite Nov 22 '14 at 09:31

2 Answers2

1

You are comparing a String with a Membership. The contains method of List will go through every item in the list and check whether "mon".equals(membership), but a Membership object will presumably never return true that it is equal to some String.

(I am making an assumption about your Membership class, that you have not overridden the equals method from java.lang.Object. It would be possible to override equals so that it does return true when compared with a String, but there are two problems. One, you are expecting not just a match when they are equal, but a substring match (where "mon" matches "Eck Salmon"), and two, implementing equals this way would be a violation of its contract. It is expected that if a.equals(b) then b.equals(a), but no java.lang.String object is ever going to return true that it is equal to one of your Membership objects, and you can't modify java.lang.String to make it do that.)

What you want to do is go through the list and check if any of the membership objects have a name that contains "mon". I assume your Membership object has a getName() method:

for (Membership membership : members) {
    if (membership.getName().contains(name)) {
        System.out.println(membership);
        return;
    }
}
System.out.println("Och Naw ... Member not found.");

It is possible to do this a little more tersely in Java 8:

Optional<Membership> maybeMember = membership.stream()
        .filter(m -> m.getName().contains(name)).findFirst();
String result = maybeMember.map(m -> m.toString())
        .orElse("Och Naw ... Member not found.");
System.out.println(result);

This finds the first item in the list that matches the condition that its name must contain the specified name, and then maps it to a string using its toString method, or else uses the default string if no matching item from the list was found.

David Conrad
  • 15,432
  • 2
  • 42
  • 54
  • Yeah, the Membership class does have getName method. However, when I try this, an error occurs: cannot find symbol - method getName() And yeah, I understand that the code I had only works when Strings are in the list. It was more me wondering how to get it with objects. – neonite Nov 21 '14 at 22:00
  • I've never seen anything this complex :P My lecturer is expecting me to do this with the For (or something similar) that I have originally. I've not learned anything as complex as what you have said I could do quite yet haha. I have given my code as pastebin links in a comment section above if you have the time to look? Thanks :) – neonite Nov 21 '14 at 22:07
  • Well, there's no need to worry about the Java 8 stuff yet. I'm only including that to make my answer as complete and comprehensive as I can. – David Conrad Nov 21 '14 at 22:08
  • Yeah and I appreciate that. :) – neonite Nov 21 '14 at 22:11
  • A few other notes, besides what people mentioned above about `found == true` and such: To print a blank line you can just do `System.out.println()`, you don't need `System.out.println(" ")`. You should declare members as `List`, not `ArrayList`. Program to the interface, not the implementation. That way, if you decide to switch to `LinkedList` later, you only have to change it in one place. – David Conrad Nov 21 '14 at 22:17
  • Thank you! This will likely be valuable information in the future :) Much appreciated! – neonite Nov 21 '14 at 22:18
0

It seems that members is a list. So when you do members.contains( name ) it wont work. You beed to do the following members.get(i).getName().contains( name ).

Luis Alves
  • 1,286
  • 12
  • 32