Find match of string in ArrayList <String>
I have one ArrayList<String>
that contains dates represented as Strings with format yyyy-MM-dd
, for example:
ArrayList<String> dates = new ArrayList<>();
dates.add("1991-02-28");
dates.add("1991-02-28");
dates.add("1994-02-21");
I would like to know the number of times that the same String
(date) appears in the list . In the above example, I would like to get the following output:
1991-02-28, 2 1994-02-21, 1
I have 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 he prints
1991-02-28, 1 1991-02-28, 1 1994-02-21, 2
I got tired and stuck and turned to SO as my last resort. Any help is appreciated.
source to share
If all it takes is just the number of numbers in which each complete row occurs in the collection List<String>
, there are Java 7
(or earlier) many trivial ways to accomplish this - not necessarily the fastest, but working.
For example, you can create Set
from a list and iterate over all the elements in a set by calling Collections.frequency(list, item)
where list
is the collection List<String>
and item
is each row of the set iteration.
Here's 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
source to share
I might be missing something, but it looks like you could just do something simple, just keep the date count in a HashMap and iterate over the HashMap for 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
source to share
Here's 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 go through the hashmap instead of the ArrayList to get the output you want.
Hope this helps!
source to share
The data structure you are describing is usually called a Multiset or sum (and usually uses it Integer
as a value, not String
).
Guava provides a very nice Multiset
thing that 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 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}
source to share