简体   繁体   English

使用Collections或我的函数计算ArrayList中对象的出现

[英]Counting the occurrence of objects in an ArrayList, using either Collections or my functions

I have an ArrayList of FlowerClass objects. 我有一个FlowerClass对象的ArrayList。 Each of these FlowerClass objects has a name. 每个FlowerClass对象都有一个名称。 I want to go through the ArrayList and count them. 我想遍历ArrayList并对其进行计数。 I want to display the amount of each. 我想显示每个的数量。 So if I have three FlowerClass objects named Rose, two named Daffodil, and one named Tulip...I want to display the following: 因此,如果我有三个名为Rose的FlowerClass对象,两个名为Daffodil的对象和一个名为Tulip的对象,我想显示以下内容:

  • Found 3 Rose 找到3朵玫瑰
  • Found 3 Daffodil 找到3个水仙花
  • Found 3 Tulip 找到3郁金香

So far, I've gotten it to count correctly using two functions I made. 到目前为止,我已经使用我制作的两个函数对它进行了正确计数。 The problem is that I iterate through the entire ArrayList...so it'll show me the results more than once. 问题是我遍历了整个ArrayList ...因此它将多次显示结果。 For example, if the user adds 3 Roses and 2 Daffodils...The output is like this: 例如,如果用户添加了3朵玫瑰和2个黄水仙...输出如下所示:

  • Found 3 Roses 找到3朵玫瑰
  • Found 3 Roses 找到3朵玫瑰
  • Found 3 Roses 找到3朵玫瑰
  • Found 2 Daffodils 找到2个水仙花
  • Found 2 Daffodils 找到2个水仙花

I know why the code does this but I don't know how to erase repeats of output. 我知道为什么代码会这样做,但是我不知道如何清除输出的重复。 I also don't know how to implement Collections correctly. 我也不知道如何正确实现Collections。 I've used Collections on an ArrayList of strings before...and it works. 在...之前,我已经在字符串的ArrayList上使用过Collections,并且它可以正常工作。 But this time I'd be using Collections on an ArrayList of Objects, and I want to check for the frequency of each specific name. 但是这一次,我将在对象的ArrayList上使用Collections,我想检查每个特定名称的出现频率。 Here is the main class: 这是主要的类:

import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;

public class MainClass {

    static ArrayList<FlowerClass> flowerPack = new ArrayList<FlowerClass>();


    public static void main(String[] args){
        Scanner input = new Scanner(System.in);

        while(true){
            System.out.println("1. Add flower to flowerpack.");
            System.out.println("2. Remove flower from the flowerpack.");
            System.out.println("3. Search for a flower in the flowerpack."); 
            System.out.println("4. Display the flowers in the flowerpack.");
            System.out.println("5. Exit the program.");

            int userChoice = input.nextInt();

            switch(userChoice){
            case 1:
                addFlower();
                break;
            case 2:
                searchFlower();
                break;
            case 3:
                displayFlowers();
                break;
            case 4:
                    System.out.println("Goodbye!");
                System.exit(0);
            }
        }
    }

    public static void addFlower(){
        if (FlowerClass.numberFlowers() == 25){
            System.out.println("There are 25 flowers in the flowerpack. Remove at least one in order to add more.");
            return;
        }
        Scanner input = new Scanner(System.in);
        System.out.println("What is the flower's name?");
        String desiredName = input.nextLine();
        System.out.println("What is the flower's color?");
        String desiredColor = input.nextLine();
        System.out.println("How many thorns does it have?");
        Scanner input2 = new Scanner(System.in);
        int desiredThorns = input2.nextInt();
        System.out.println("What does it smell like?");
        String desiredSmell = input.nextLine();
        flowerPack.add(new FlowerClass(desiredName, desiredColor, desiredThorns, desiredSmell));
    }

    public static void searchFlower(){
        System.out.println("Enter the flower you want to search for.");
        Scanner input = new Scanner(System.in);
        String userChoice = input.nextLine();
        int occurrences  = 0;

        for (FlowerClass flower: flowerPack){
            String name = flower.getName();
            if (userChoice.equals(name)){
                occurrences++;
            }

            else if(occurrences == 0){
                System.out.println("Match not found.");
                return;
            }
        }

        System.out.println("Found " + occurrences + " " + userChoice);
    }

    public static void searchFlower(String desiredFlower){
        int occurrences = 0;

        String userChoice = desiredFlower;
        for (FlowerClass flower: flowerPack){
            String name = flower.getName();
            if (userChoice.equals(name)){
            occurrences++;
            }
        }

        System.out.println("Found " + occurrences + " " + userChoice);
    }

    public static void displayFlowers(){
        int repeats = 0;

        /*for (FlowerClass flower: flowerPack){
            System.out.println(flower.getName());
        }
        System.out.println("Number of flowers in pack: " + FlowerClass.numberFlowers());*/

            //int occurrences = Collections.frequency(flowerPack, name);
            //System.out.println(name + ": " + occurrences);
        for (FlowerClass flower: flowerPack){
            String name = flower.getName();
            searchFlower(name);
        }
    }
}

Here is the FlowerClass: 这是FlowerClass:

public class FlowerClass {

    public static int numberOfFlowers = 0;
    public String flowerName = null;
    public String flowerColor = null;
    public int numberThorns = 0;
    public String flowerSmell = null;

    FlowerClass(){

    }

    FlowerClass(String desiredName, String desiredColor, int desiredThorns, String desiredSmell){
        flowerName = desiredName;
            flowerColor = desiredColor;
        numberThorns = desiredThorns;
        flowerSmell = desiredSmell;
        numberOfFlowers++;
    }

    public void setName(String desiredName){
        flowerName = desiredName;

    }

    public String getName(){
        return flowerName;
    }

    public static int numberFlowers(){
        return numberOfFlowers;
    }
}

If you look at my last function in the main class, you'll see that I commented out the way I was attempting to implement Collections.frequency. 如果您查看我在主类中的最后一个函数,您会发现我已注释掉尝试实现Collections.frequency的方式。 I also tried making a multidimensional array of Strings and storing the names of the flowers and also the number of flowers in the arrays. 我还尝试制作一个字符串的多维数组,并存储花朵的名称以及数组中花朵的数量。 This was counting everything correctly but I wasn't sure how to display the names alongside the counts. 这样可以正确计数所有内容,但是我不确定如何在计数旁边显示名称。 It was getting very messy so I abandoned that attempt for now in favor of trying these other two options. 事情变得非常混乱,所以我暂时放弃了这一尝试,转而尝试另外两个选项。 If I can find a way to erase repeated lines of output (or if I can find a way to get Collections to work) then I won't need to tinker with the multidimensional array. 如果我可以找到一种方法来消除重复的输出行(或者可以找到一种方法来使Collections正常工作),那么就不需要修改多维数组了。

Any tips would be very much appreciated. 任何提示将不胜感激。 Thank you for your time. 感谢您的时间。

You could put your Flower(s) in a Set . 您可以将您的Flower放在Set But the easiest solution I can think of is to sort your flowers. 但是我能想到的最简单的解决方案是对花朵进行排序。 So first, implement a Comparator<FlowerClass> 所以首先,实现一个Comparator<FlowerClass>

public static class FlowerComparator implements Comparator<FlowerClass> {
  @Override
  public int compare(FlowerClass o1, FlowerClass o2) {
    return o1.getName().compareTo(o2.getName());
  }
}

Then you can sort with Collections.sort(List, Comparator) 然后,您可以使用Collections.sort(List, Comparator)排序

FlowerComparator flowerComparator = new FlowerComparator();
Collections.sort(flowerPack, flowerComparator);

And then your for loop needs to be something like this (to stop searching for the same flower), 然后您的for循环必须是这样的(停止搜索同一朵花),

String lastName = null;
for (int i = 0; i < flowerPack.size(); i++){
  FlowerClass flower = flowerPack.get(i);
  String name = flower.getName();
  if (lastName == null || !lastName.equals(name)) {
    lastName = name;
    searchFlower(name); // or return the number found, and then add that count to i.
  }
 }

Interesting code, but it doesn't work the way I would do it. 有趣的代码,但是它不能像我那样做。

In this current case as you've done it, you would need to keep track of the flower names you have already encountered: 在当前情况下,您需要跟踪已经遇到的花朵名称:

public static void displayFlowers(){
    //int repeats = 0;
    List<String> displayedFlowerTypes = new ArrayList<String>();
    for (FlowerClass flower: flowerPack){
        String name = flower.getName();
        if(!displayedFlowerTypes.contains(name))
        {
            displayedFlowerTypes.add(name);
            searchFlower(name);
        }
    }
}

What I would rather do is maintain a Map that keeps track of the counts of the flower types, and just obtain the numbers for the types from that: 我宁愿做的是维护一个Map,该Map跟踪花朵类型的数量,并从中获取类型的数字:

public class MainClass {

static List<FlowerClass> flowerPack = new ArrayList<FlowerClass>();
static Map<String, Integer> flowerCount = new HashMap<String, Integer>();

public static void addFlower() {
    if (FlowerClass.numberFlowers() == 25) {
        System.out.println("There are 25 flowers in the flowerpack. Remove at least one in order to add more.");
        return;
    }
    Scanner input = new Scanner(System.in);
    System.out.println("What is the flower's name?");
    String desiredName = input.nextLine();
    System.out.println("What is the flower's color?");
    String desiredColor = input.nextLine();
    System.out.println("How many thorns does it have?");
    Scanner input2 = new Scanner(System.in);
    int desiredThorns = input2.nextInt();
    System.out.println("What does it smell like?");
    String desiredSmell = input.nextLine();
    flowerPack.add(new FlowerClass(desiredName, desiredColor, desiredThorns, desiredSmell));
    if(!flowerCount.containsKey(desiredName))
    {
        flowerCount.put(desiredName, 1);
    }
    else
    {
        int currentCount = flowerCount.get(desiredName);
        flowerCount.put(desiredName, currentCount+1));
    }
}

That way, you could just display the flowers as the following: 这样,您可以将花朵显示如下:

    public static void displayFlowers() {
        for (String name : flowerCount.keySet()) {
            //searchFlower(name);
            System.out.println("Found " + flowerCount.get(name) + " " + name);
        }
    }

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

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