计算 ArrayList 中特定变量的出现次数
Count the occurences of a particular variable inside an ArrayList
在我的 class Feeds
中,我和其他成员一起有一个名为 "Date" 的成员变量,它是 String
类型。我有 ArrayList
个 Feeds
个对象。我想找到具有相同日期字符串的对象的出现。然后可以将出现次数放入 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);
}
如果您正确覆盖 equals
并且在 Feeds
class 到 return true
两个 Feeds
实例中,您的代码将工作具有相同的日期(因为如果您尝试将相同的键两次放入 Map 中,则新值将覆盖旧值,并且由于在您的情况下这些值也将相同,因此不会有任何区别)。但是,每次调用 Collections.frequency
都会遍历整个列表,这会给您带来 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);
}
}
为什么不直接使用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);
}
我没有测试代码,但它应该可以工作。
除了给你一个简单的解决方案,我冒昧地修复了你代码中的一些东西,请看一看:
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);
}
}
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]++;
利用参考之美:)
在我的 class Feeds
中,我和其他成员一起有一个名为 "Date" 的成员变量,它是 String
类型。我有 ArrayList
个 Feeds
个对象。我想找到具有相同日期字符串的对象的出现。然后可以将出现次数放入 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);
}
如果您正确覆盖 equals
并且在 Feeds
class 到 return true
两个 Feeds
实例中,您的代码将工作具有相同的日期(因为如果您尝试将相同的键两次放入 Map 中,则新值将覆盖旧值,并且由于在您的情况下这些值也将相同,因此不会有任何区别)。但是,每次调用 Collections.frequency
都会遍历整个列表,这会给您带来 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);
}
}
为什么不直接使用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);
}
我没有测试代码,但它应该可以工作。
除了给你一个简单的解决方案,我冒昧地修复了你代码中的一些东西,请看一看:
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);
}
}
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]++;
利用参考之美:)