DevOpsSauce
DevOpsSauce

Reputation: 1387

ArrayList not printing duplicates (Java)

I didn't think I would have as much trouble since I've done this with a brute force method with regular arrays. I'm trying to use Collections.frequency to group together repeated entries from a user and display the number of times each entry occurs (if more than once); however, the output just prints as they are entered. I have two classes, which I will show below:

    public class Flower {

private String name;
private String color;
private String smell;
private String hasThorns;

public Flower(String name, String color, String smell, String hasThorns) {
    this.name = name;
    this.color = color;
    this.smell = smell;
    this.hasThorns = hasThorns;
}
public void setName(String name) {
    this.name = name;
}
public void setColor(String color) {
    this.color = color;
}
public void setSmell(String smell) {
    this.smell = smell;
}
public void setThorns(String hasThorns) {
    this.hasThorns = hasThorns;
}
public String getName() {
    return name;
}
public String getColor() {
    return color;
}
public String getSmell() {
    return smell;
}
public String getThorns() {
    return hasThorns;
}
public String toString() {
    return "Name: " + this.name + ", Color: " + this.color + ", Scent? " + this.smell + ", Thorns? " + this.hasThorns;
}
}//end Flower class



    import java.util.*;

public class Assignment3 {
String name = new String();
String color = new String();
String smell = new String();
String hasThorns = new String();

//ArrayList<Flower> flowerPack = new ArrayList<Flower>();
boolean found = false;
public static void main(String[] args) {
    new Assignment3();
}

// This will act as our program switchboard
public Assignment3() {
    Scanner input = new Scanner(System.in);
    ArrayList<Flower> flowerPack = new ArrayList<Flower>();

    System.out.println("Welcome to my flower pack interface.");
    System.out.println("Please select a number from the options below");
    System.out.println("");

    while (true) {
        // Give the user a list of their options
        System.out.println("1: Add an item to the pack.");
        System.out.println("2: Remove an item from the pack.");
        System.out.println("3: Search for a flower.");
        System.out.println("4: Display the flowers in the pack.");
        System.out.println("5: Filter flower pack by incomplete name");
        System.out.println("0: Exit the flower pack interface.");

        // Get the user input
        int userChoice = input.nextInt();

        switch (userChoice) {
            case 1:
                addFlower(flowerPack);
                break;
            case 2:
                removeFlower(flowerPack);
                break;
            case 3:
                searchFlowers(flowerPack);
                break;
            case 4:
                displayFlowers(flowerPack);
                break;
            case 5:
                filterFlowers(flowerPack);
                break;
            case 0:
                exitInterface();
                break;
            default:
                System.out.println("Invalid entry. \nPlease choose between 1-5, or 0: ");
                break;
        }
    }
}
private void addFlower(ArrayList<Flower> flowerPack) {
    // TODO: Add a flower that is specified by the user
    Flower newFlower = new Flower(name, color, smell, hasThorns);

    Scanner input = new Scanner(System.in);

    if(flowerPack.size() < 25)
    {
        System.out.println("Enter the name of the flower you wish to add: ");
        newFlower.setName(input.nextLine());
        System.out.println("Enter the color of the flower: ");
        newFlower.setColor(input.nextLine());
        System.out.println("Does the flower have a scent? Yes or No: ");
        newFlower.setSmell(input.nextLine());
        System.out.println("Does the flower have thorns? Yes or No: ");
        newFlower.setThorns(input.nextLine());

        flowerPack.add(newFlower);
    }
    else
    {
        System.out.println("You may only hold 25 flowers in your flower pack. Please remove at least one before adding another.");
    }
}
private void removeFlower(ArrayList<Flower> flowerPack) {
    // TODO: Remove a flower that is specified by the user
    Scanner input = new Scanner(System.in);

    System.out.println("Enter the name of the flower you want to remove: ");
    String deleteName = input.nextLine();
    System.out.println("Enter the color of the flower you want to remove: ");
    String deleteColor = input.nextLine();
    System.out.println("Is this a flower with a scent? Yes or No: ");
    String deleteSmell = input.nextLine();
    System.out.println("Is this a flower with thorns? Yes or No: ");
    String deleteThorns = input.nextLine();

    for(int i = 0; i < flowerPack.size(); i++) {
        if(flowerPack.get(i).getName().equals(deleteName) && flowerPack.get(i).getColor().equals(deleteColor) && flowerPack.get(i).getSmell().equals(deleteSmell) && flowerPack.get(i).getThorns().equals(deleteThorns))
        {
            flowerPack.remove(i);
            found = true;
            break;
        }
        if(found)
        {
            System.out.println("That flower was successfully removed from your inventory.");
        }
        else
        {
            System.out.println("That flower was not found in your inventory.");
        }
    }
}
private void searchFlowers(ArrayList<Flower> flowerPack) {
    // TODO: Search for a user specified flower

}

This is where I am having the problem. I haven't started the other methods (search, filter) since I want it to display correctly before moving on.

private void displayFlowers(ArrayList<Flower> flowerPack) {
    // TODO: Display flowers using any technique you like

    for(Flower flower : flowerPack) {
        int duplicates = Collections.frequency(flowerPack, flower);
        System.out.println(flower + " - " + duplicates);
    }
}

private void filterFlowers (ArrayList<Flower> flowerPack) {
    // TODO Filter flower results

}
private void exitInterface() {
    Scanner input = new Scanner(System.in);
    System.out.println("Are you sure you want to exit the flower pack interface? Y or N: ");
    while(true) {
        String answer = input.next();
        if(!"Y".equalsIgnoreCase(answer) && !"N".equalsIgnoreCase(answer))
        {
            System.out.println("Please enter Y or N (not case-sensitive): ");
        }
        if("Y".equalsIgnoreCase(answer))
        {
            System.out.println("Thank you for using the flower pack interface. See ya later!");
            System.exit(0);
        }
        if("N".equalsIgnoreCase(answer))
        {
            break;
        }
    }
}
}

I've seen examples with Maps/HashSets, but I'm too unfamiliar with those concepts to utilize them at this point.

This is the output, which is incorrect. Could someone give me a hint as to where I went wrong?

    Name: rose, Color: red, Scent? yes, Thorns? yes - 1
    Name: rose, Color: red, Scent? yes, Thorns? yes - 1
    Name: rose, Color: pink, Scent? yes, Thorns? no - 1
    Name: daffodil, Color: yellow, Scent? yes, Thorns? no - 1

As you can see, the first two entries should read as one, but with -2:

Like:

    Name: rose, Color: red, Scent? yes, Thorns? yes - 2

Upvotes: 0

Views: 290

Answers (2)

hinneLinks
hinneLinks

Reputation: 3736

Your flower Class needs a equals and hashcode Method, otherwise java cant tell if two flower objects are the same.

Upvotes: 1

janos
janos

Reputation: 124656

Collections.frequency uses Flower.equals to decide if two flowers are the same or not. Since you haven't overridden the default implementation of equals, all instances of Flower appear to be unique.

You can use your IDE to generate an equals (and hashCode) implementation that should work well, and then the frequency count will become correct, as logically equal flowers will be detected as such.

For example, as generated by IntelliJ, add this in Flower:

@Override
public boolean equals(Object o) {
    if (this == o) {
        return true;
    }
    if (o == null || getClass() != o.getClass()) {
        return false;
    }

    Flower flower = (Flower) o;

    if (color != null ? !color.equals(flower.color) : flower.color != null) {
        return false;
    }
    if (hasThorns != null ? !hasThorns.equals(flower.hasThorns) : flower.hasThorns != null) {
        return false;
    }
    if (name != null ? !name.equals(flower.name) : flower.name != null) {
        return false;
    }
    if (smell != null ? !smell.equals(flower.smell) : flower.smell != null) {
        return false;
    }

    return true;
}

@Override
public int hashCode() {
    int result = name != null ? name.hashCode() : 0;
    result = 31 * result + (color != null ? color.hashCode() : 0);
    result = 31 * result + (smell != null ? smell.hashCode() : 0);
    result = 31 * result + (hasThorns != null ? hasThorns.hashCode() : 0);
    return result;
}

Upvotes: 0

Related Questions