views:

2854

answers:

5

I need to see if a string value matches with an object value, but why won't this work?

public int countPacks(String flavour) {
    int counter = 0;
    for(int index = 0; index < packets.size(); index++) {            
        if (packets.equals(flavour)) {
           counter ++;
        }
        else {
           System.out.println("You have not entered a correct flavour");
        }
    } 
    return counter; 
}
+3  A: 

You probably mean something like

if (packets.get(index).equals(flavour)) { ...

micro
+12  A: 

What is "packets"? It's not going to be a string - so how would it equal a string?

I suspect you meant your test to be:

if (packets.get(index).equals(flavour))

However you're still going to print out "You have not entered a correct flavour" for every packet of the "wrong" flavour even if there's one with the right flavour!

I suspect you want to move the error reporting to the end of the method, after the loop, and only execute it if counter == 0

Jon Skeet
A: 

You should do it this way to be certian you really are comparing strings in the most foolproof way possible.

I also fixed your loop

public int countPacks(String flavour, List packets)
    {
        int counter = 0;
        for (Iterator iter = packets.iterator(); iter.hasNext();) {
      Map packet = (Map) iter.next();

            if (packet.get("flavour").toString().equalsIgnoreCase(flavour)) {
             counter ++;
            }
          else {
            System.out.println("You have not entered a correct flavour");
            }
        } 
        return counter; 
    }
mugafuga
+2  A: 

Assuming packets is a Collection (and you're using JDK 1.5 or greater), you could also just make the method

public int countPacks(String flavor) { int numOccurrences = java.util.Collections.frequency(packets, flavor); if(numOccurrences == 0) { System.out.println("You have not entered a correct flavor"); } return numOccurrences; }

+2  A: 

A problem with methods declared in Object is that there is a lack of static type checking in their use. The same applies to synchronized, where it is common to lock the wrong object.

In this case Object.equals(Object) works with any two objects. You have used the collection, packets, instead of getting an element from it. The important question is not how did this particular bug come about, but how can we prevent it from occurring in the first place.

First of all, use generics and get assign each element for the iteration to a statically typed local:

public int countPacks(String flavour) {
    // [ The field represents a count. ]
    int count = 0;
    for(int index=0; index<packets.size(); ++index) {
        String packet = packets.get(index);
        if (packet.equals(flavour)) {
           ++count;
        }
    } 
    // [The error mesage was printed for each non-match.
    //  Even this is probably wrong,
    //    as it should be valid to have no packs of a valid flavour.
    //  Having the message in this method is actually a bit confused.]
    if (count == 0) {
        System.out.println("You have not entered a correct flavour");
    }
    return count; 
}

We can further tidy this up using the enhanced for loop.

public int countPacks(String flavour) {
    int count = 0;
    for(String packet : packets) {
        if (packet.equals(flavour)) {
           ++count;
        }
    } 
    if (count == 0) {
        System.out.println("You have not entered a correct flavour");
    }
    return count; 
}

That looks clearer, but a good programmer knows his/her libraries.

public int countPacks(String flavour) {
    int count = Collections.frequency(packets, flavour);
    if (count == 0) {
        System.out.println("You have not entered a correct flavour");
    }
    return count; 
}

You might also consider a Map<String,Integer> instead of the collection.

Tom Hawtin - tackline