简体   繁体   English

ArrayList不打印重复项(Java)

[英]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); 我正在尝试使用Collections.frequency将来自用户的重复条目归为一组,并显示每个条目出现的次数(如果不止一次); 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. 我已经看到了有关Maps / HashSets的示例,但是我现在还不熟悉这些概念,因此无法使用它们。

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: 如您所见,前两个条目应读为1,但带有-2:

Like: 喜欢:

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

您的flower类需要一个equals和hashcode方法,否则java不能判断两个flower对象是否相同。

Collections.frequency uses Flower.equals to decide if two flowers are the same or not. Collections.frequency使用Flower.equals来确定两个花朵是否相同。 Since you haven't overridden the default implementation of equals , all instances of Flower appear to be unique. 由于您尚未覆盖equals的默认实现,因此Flower所有实例似乎都是唯一的。

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. 您可以使用IDE生成应该运行良好的equals (和hashCode )实现,然后频率计数将变得正确,因为这样将检测到逻辑上相等的花朵。

For example, as generated by IntelliJ, add this in Flower : 例如,由IntelliJ生成,将其添加到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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM