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.