Here is one possible solution if you didn't want to rely on another library and wanted to maintain backward compatibility with older JVMs. It isn't the best, or the easiest to use, but it does work.
FrequencyUtil.java
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
public class FrequencyUtil
{
private static FrequencyUtil SINGLETON;
private static FrequencyUtil getInstance()
{
if (FrequencyUtil.SINGLETON == null)
{
FrequencyUtil.SINGLETON = new FrequencyUtil();
}
return FrequencyUtil.SINGLETON;
}
public static <X> Map<X, Integer> frequency(final Collection<X> objects, final Comparator<X> comparator)
{
Map<ComparatorWrapper<X>, Integer> frequencies = new HashMap<ComparatorWrapper<X>, Integer>();
for (X object : objects)
{
ComparatorWrapper<X> wrapper = FrequencyUtil.getInstance().new ComparatorWrapper<X>(object, comparator);
Integer count = frequencies.get(wrapper);
frequencies.put(wrapper, (count == null) ? 1 : count + 1);
}
// unwrap the frequencies
Map<X, Integer> frequenciesRaw = new HashMap<X, Integer>();
for (ComparatorWrapper<X> wrapper : frequencies.keySet())
{
frequenciesRaw.put(wrapper.getObject(), frequencies.get(wrapper));
}
return frequenciesRaw;
}
private class ComparatorWrapper<Z>
{
private Z object;
private Comparator<Z> comparator;
ComparatorWrapper(final Z object, final Comparator<Z> comparator)
{
this.object = object;
this.comparator = comparator;
return;
}
public Z getObject()
{
return this.object;
}
@Override
public int hashCode()
{
return 0;
}
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object obj)
{
if ((obj == null) || !(obj instanceof ComparatorWrapper))
{
return false;
}
return this.comparator.compare(this.object, ((ComparatorWrapper<Z>) obj).getObject()) == 0;
}
}
}
FrequencyTest.java
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
public class FrequencyTest
{
public void test()
{
List<Pin> pins = new ArrayList<Pin>();
Pin pin1 = new Pin();
Pin pin2 = new Pin();
Pin pin3 = new Pin();
pin1.setPinType("typeA");
pin2.setPinType("typeB");
pin3.setPinType("typeA");
pin1.setPinNumber("50");
pin2.setPinNumber("50");
pin3.setPinNumber("80");
pin1.setInsertDate(Calendar.getInstance().getTime());
pin2.setInsertDate(Calendar.getInstance().getTime());
pin3.setInsertDate(Calendar.getInstance().getTime());
pins.add(pin1);
pins.add(pin2);
pins.add(pin3);
Comparator<Pin> pinTypeComparator = new Comparator<Pin>()
{
@Override
public int compare(final Pin o1, final Pin o2)
{
return o1.getPinType().compareTo(o2.getPinType());
}
};
Comparator<Pin> pinNumberComparator = new Comparator<Pin>()
{
@Override
public int compare(final Pin o1, final Pin o2)
{
return o1.getPinNumber().compareTo(o2.getPinNumber());
}
};
Comparator<Pin> insertDateComparator = new Comparator<Pin>()
{
private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
@Override
public int compare(final Pin o1, final Pin o2)
{
return this.sdf.format(o1.getInsertDate()).compareTo(this.sdf.format(o2.getInsertDate()));
}
};
Map<Pin, Integer> pinTypeFrequency = FrequencyUtil.frequency(pins, pinTypeComparator);
Map<Pin, Integer> pinNumberFrequency = FrequencyUtil.frequency(pins, pinNumberComparator);
Map<Pin, Integer> insertDateFrequency = FrequencyUtil.frequency(pins, insertDateComparator);
System.out.println("pinTypeFrequency");
for (Pin pin : pinTypeFrequency.keySet())
{
System.out.println(pin.getPinType() + ": " + pinTypeFrequency.get(pin));
}
System.out.println();
System.out.println("pinNumberFrequency");
for (Pin pin : pinNumberFrequency.keySet())
{
System.out.println(pin.getPinNumber() + ": " + pinNumberFrequency.get(pin));
}
System.out.println();
System.out.println("insertDateFrequency");
for (Pin pin : insertDateFrequency.keySet())
{
System.out.println(pin.getInsertDate().toString() + ": " + insertDateFrequency.get(pin));
}
}
public static void main(String[] args)
{
try
{
new FrequencyTest().test();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
System.exit(0);
}
}
Pin.java
import java.util.Date;
public class Pin
{
private String pinNumber;
private String pinType;
private Date insertDate;
public String getPinNumber()
{
return pinNumber;
}
public void setPinNumber(String pinNumber)
{
this.pinNumber = pinNumber;
}
public String getPinType()
{
return pinType;
}
public void setPinType(String pinType)
{
this.pinType = pinType;
}
public Date getInsertDate()
{
return insertDate;
}
public void setInsertDate(Date insertDate)
{
this.insertDate = insertDate;
}
}
output
pinTypeFrequency typeB: 1 typeA: 2
pinNumberFrequency 80: 1 50: 2
insertDateFrequency Mon Jun 22 12:09:19 EDT 2015: 3
Just for fun and historical reference, a Java 1.2 version:
FrequencyUtil12.java
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class FrequencyUtil
{
private static FrequencyUtil SINGLETON;
private static FrequencyUtil getInstance()
{
if (FrequencyUtil.SINGLETON == null)
{
FrequencyUtil.SINGLETON = new FrequencyUtil();
}
return FrequencyUtil.SINGLETON;
}
public static Map frequency(final Collection objects, final Comparator comparator)
{
Map frequencies = new HashMap();
Iterator iter = objects.iterator();
while (iter.hasNext())
{
Object object = iter.next();
ComparatorWrapper wrapper = FrequencyUtil.getInstance().new ComparatorWrapper(object, comparator);
Integer count = (Integer) frequencies.get(wrapper);
frequencies.put(wrapper, (count == null) ? 1 : count + 1);
}
// unwrap the frequencies
Map frequenciesRaw = new HashMap();
Iterator keys = frequencies.keySet().iterator();
while (keys.hasNext())
{
ComparatorWrapper wrapper = (ComparatorWrapper) keys.next();
frequenciesRaw.put(wrapper.getObject(), frequencies.get(wrapper));
}
return frequenciesRaw;
}
private class ComparatorWrapper
{
private Object object;
private Comparator comparator;
ComparatorWrapper(final Object object, final Comparator comparator)
{
this.object = object;
this.comparator = comparator;
return;
}
public Object getObject()
{
return this.object;
}
public int hashCode()
{
return 0;
}
public boolean equals(Object obj)
{
if ((obj == null) || !(obj instanceof ComparatorWrapper))
{
return false;
}
return this.comparator.compare(this.object, ((ComparatorWrapper) obj).getObject()) == 0;
}
}
}