我有ArrayList<String>
个日期,表示为格式为yyyy-MM-dd
的字符串,例如:
ArrayList<String> dates = new ArrayList<>();
dates.add("1991-02-28");
dates.add("1991-02-28");
dates.add("1994-02-21");
我想知道列表中出现相同String
(日期)的次数。在上面的示例中,我想实现以下输出:
1991-02-28, 2
1994-02-21, 1
我已尝试过以下代码
ArrayList<String> dates = new ArrayList<>();
dates.add("1991-02-28");
dates.add("1991-02-28");
dates.add("1994-02-21");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
HashMap<String, String> dateCount = new HashMap<String, String>();
String first = dates.get(0);
int count = 1;
dateCount.put(first, String.valueOf(count));
for (int i = 1; i < dates.size(); i++) {
if (first.equals(dates.get(i))) {
count++;
} else {
first = dates.get(i);
dateCount.put(dates.get(i), String.valueOf(count));
count = 0;
}
}
for (String date : dates) {
String occ = dateCount.get(date);
System.out.println(date + ", " + occ);
}
但它打印
1991-02-28, 1
1991-02-28, 1
1994-02-21, 2
作为最后的手段,我累了,被困,并转向SO。任何帮助表示赞赏。
答案 0 :(得分:3)
我可能会遗漏一些东西,但看起来你可以做这样简单的事情,只需在HashMap中保留Dates的数量,然后迭代HashMap以获得输出:
ArrayList<String> dates = new ArrayList<>();
dates.add("1991-02-28");
dates.add("1991-02-28");
dates.add("1994-02-21");
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
HashMap<String, Integer> dateCount = new HashMap<String, Integer>();
for (int i = 0; i < dates.size(); i++) {
String date = dates.get(i);
Integer count = dateCount.get(date);
if (count == null){
dateCount.put(date, 1);
}
else{
dateCount.put(date, count + 1);
}
}
for(String key : dateCount.keySet()){
Integer occ = dateCount.get(key);
System.out.println(key + ", " + occ);
}
输出:
1991-02-28, 2
1994-02-21, 1
答案 1 :(得分:2)
我尚未调试您的逻辑,但您可以使用Google Guava的index方法执行groupBy。
答案 2 :(得分:2)
这是正确的解决方案:
public class mainClass {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> dates = new ArrayList<>();
dates.add("1991-02-28");
dates.add("1991-02-28");
dates.add("1994-02-21");
//SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
HashMap<String, Integer> dateCount = new HashMap<String, Integer>();
// String first = dates.get(0);
// int count = 1;
// dateCount.put(first, String.valueOf(count));
// for (int i = 1; i < dates.size(); i++) {
// if (first.equals(dates.get(i))) {
// count++;
// } else {
// first = dates.get(i);
// dateCount.put(dates.get(i), String.valueOf(count));
// count = 0;
// }
// }
for(int i= 0; i < dates.size();i++)
{
if(dateCount.containsKey(dates.get(i)))
{
dateCount.put(dates.get(i),dateCount.get(dates.get(i))+1);
}
else
dateCount.put(dates.get(i),1);
}
for (String date : dates) {
int occ = dateCount.get(date);
System.out.println(date + ", " + occ);
}
}
}
但是,你需要遍历hashmap而不是ArrayList来获得所需的输出。
希望这有帮助!
答案 3 :(得分:2)
您描述的数据结构通常称为Multiset或Bag(通常使用Integer
作为值,而不是String
)。
Guava提供了一个非常好的Multiset
接口,这使得此操作变得微不足道:
Multiset<String> counts = HashMultiset.create();
for(String date : dates) {
counts.add(date);
}
System.out.println(counts);
[1991-02-28 x 2, 1994-02-21]
即使没有番石榴,你也可以假装一个带有Map<T, Integer>
和一些小样板的Multiset:
Map<String, Integer> counts = new HashMap<>();
for(String date : dates) {
Integer count = counts.get(date);
if(count == null) {
count = 0;
}
counts.put(date, count+1);
}
System.out.println(counts);
{1991-02-28=2, 1994-02-21=1}
答案 4 :(得分:1)
如果所需要的仅仅是List<String>
集合中每个完整字符串出现次数的计数,那么Java 7
中有许多无关紧要的方式(或这样做 - 不一定是最快的,而是工作。
例如,可以从列表中创建Set
并迭代集合中的所有项目,调用Collections.frequency(list, item)
,其中list
是List<String>
集合,{ {1}}是集迭代的每个字符串。
这是一个简单的实现:
item
<强>输出:强>
public static class FrequencyCount {
public static void main(String[] args){
java.util.ArrayList<String> dates = new java.util.ArrayList<>();
dates.add("1991-02-28");
dates.add("1991-02-28");
dates.add("1994-02-21");
java.util.Set<String> uniqueDates = new java.util.HashSet<String>(dates);
for (String date : uniqueDates) {
System.out.println(date + ", " + java.util.Collections.frequency(dates, date));
}
}
}