【问题标题】:Count the occurences of a particular variable inside an ArrayList计算 ArrayList 中特定变量的出现次数
【发布时间】:2015-03-20 22:38:19
【问题描述】:

在我的班级Feeds 中,我和其他成员有一个名为“Date”的成员变量,它属于String 类型。我有一个ArrayListFeeds 对象。我想找到具有相同日期字符串的对象的出现。然后可以将出现的次数放入 HashMap 中,其中包含 String 作为键的日期和作为值的出现次数。

类似的东西:

List<Feeds> m_feeds = new ArrayList<Feeds>();

//add all feeds objects
m_feeds.add(...);

int occurrences = 0;
HashMap<String, Integer> repeatedDatabase = new HashMap<String, Integer>();

for (Feeds f : m_feeds){
     occurrences = Collections.frequency(m_feeds, f.date);
     // i know this method compares objects but i want to know how 
    // only a single variable can be done
    repeatedDatabase.put(f.date, occurrences);
}

【问题讨论】:

    标签: java arraylist collections hashmap


    【解决方案1】:

    除了给你一个简单的解决方案,我冒昧地修复了你代码中的一些东西,请看一下:

    List<Feeds> mFeeds = new ArrayList<>(); //If you are using Java 7+ you do not need to declare explicitly the Type in Diamonds. If you aren't, ignore this. Also fixed name to adapt to Java standards.
    
    //add all feeds objects
    m_feeds.add(...);
    
    HashMap<String, Integer> repeatedDatabase = new HashMap<>(); //See Above.
    
    for (Feeds f : m_feeds){
        String s = f.date; //Suggestion: use a getter method, do not make public variables accessible outside class
        Integer i = repeatedDatabase.get(s);
        if (i == null){
            repeatedDatabase.put(s, 1);
        } else {
            repeatedDatabase.put(s, i+1);
        } 
    }
    

    【讨论】:

    • 这如何计算 m_feeds 中重复的完整日期
    • 它试图从日期键中获取一个整数。如果地图中有一个,则结果将为整数,如果没有,则结果将为空。如果为 null,则在映射中添加一个新 Set,如果不是,则将映射到 date 的整数加一。
    • @stud91 如果你愿意,你可以这样写 if\else 语句:repeatDatabase.put(s, i == null ? 1 : i+1);但这只是眼花缭乱。
    【解决方案2】:

    如果您正确覆盖 equals 并在 Feeds 类中为具有相同日期的两个 Feeds 实例返回 true,您的代码将起作用(因为如果您尝试在 Map 中放置相同的键两次,新值将覆盖旧值,并且由于在您的情况下这些值也相同,因此没有区别)。但是,每次调用 Collections.frequency 都会遍历整个 List,这会给您带来 O(n^2) 时间复杂度。

    提高效率的一种方法:

    for (Feeds f : m_feeds){
        if (!repeatedDatabase.containsKey(f.date)) {
            occurrences = Collections.frequency(m_feeds, f.date);
            repeatedDatabase.put(f.date, occurrences);
        }
    }
    

    这仍然会进行不必要的迭代。它会为每个唯一日期调用一次Collections.frequency,这意味着您将迭代列表的次数与唯一日期一样多。

    更高效的实现根本不会使用Collection.frequency。相反,您只需在列表中迭代一次并自己计算每个日期的出现次数。这会给你一个 O(n) 的时间复杂度。

    for (Feeds f : m_feeds){
        if (!repeatedDatabase.containsKey(f.date)) {
            repeatedDatabase.put(f.date, 1);
        } else {
            repeatedDatabase.put(f.date, repeatedDatabase.get(f.date)+1);
        }
    }
    

    【讨论】:

      【解决方案3】:

      为什么不直接使用hashMap?

      你可以做类似的事情

      HashMap<String,Iteger> map = new HashMap<>();
      for (Feeds f : m_feeds){
          if (map.contains(f.getDate()) { // use the method to get the date
              map.put(f.getDate(),map.get(f)+1);
          else
              map.put(f.getDate(),1);
      }
      

      我没有测试代码,但它应该可以工作。

      【讨论】:

        【解决方案4】:

        Angelo 的回答的一个小更新..将它推得更远..您也可以像这样使用 string,int[] 的映射

        Map<String,int[]> map = new HashMap<>();
        int[] countArray = map.get(key);
        if(countArray == null)
           map.put(key, new int[]{0});
        else
          countArray[0]++;
        

        利用引用的美 :)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-08
          • 1970-01-01
          • 2019-01-15
          • 2022-01-18
          • 2013-11-13
          • 2022-12-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多