Reputation: 6717
I have an ArrayList<String>
containing dates represented as Strings with the format yyyy-MM-dd
, e.g:
ArrayList<String> dates = new ArrayList<>();
dates.add("1991-02-28");
dates.add("1991-02-28");
dates.add("1994-02-21");
I'd like to know the number of times the same String
(date) appears in the list. In the example above, I'd like to achieve the following output:
1991-02-28, 2
1994-02-21, 1
I've tried the following code
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);
}
But it prints
1991-02-28, 1
1991-02-28, 1
1994-02-21, 2
I'm tired, stuck, and turning to SO as a last resort. Any help is appreciated.
Upvotes: 3
Views: 214
Reputation: 43322
I may be missing something, but it looks like you could just do something simple like this, just keep the count of Dates in the HashMap, and iterate over the HashMap for the output:
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);
}
Output:
1991-02-28, 2
1994-02-21, 1
Upvotes: 3
Reputation: 48794
The data structure you're describing is commonly called a Multiset or Bag (and generally uses Integer
as the value, not String
).
Guava provides a very nice Multiset
interface, which makes this operation trivial:
Multiset<String> counts = HashMultiset.create();
for(String date : dates) {
counts.add(date);
}
System.out.println(counts);
[1991-02-28 x 2, 1994-02-21]
Even without Guava, you can fake a Multiset with a Map<T, Integer>
and a little boilerplate:
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}
Upvotes: 2
Reputation: 19895
If all that is required is just a count of the number of occurrences of each full string in a List<String>
collection, there are numerous trivial ways in Java 7
(or earlier) for doing it - not necessarily the fastest ones, but working.
For example, one can create a Set
from the list and iterate over all items in the set, calling Collections.frequency(list, item)
, where list
is the List<String>
collection and item
is each string of the set iteration.
Here is a simple implementation:
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));
}
}
}
Output:
1994-02-21, 1
1991-02-28, 2
Upvotes: 1
Reputation: 158
Here is the correct solution:
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);
}
}
}
But, you need to traverse through the hashmap instead of ArrayList to get the desired ouput..
Hope This helps!
Upvotes: 2
Reputation: 38511
I haven't debugged your logic yet, but you can use Google Guava's index method to perform a groupBy.
Upvotes: 2