我有List
个Pin
个对象(List<Pin>
),其中Pin
类具有以下属性:
String pinNumber, String pinType, Date insertDate
我希望得到一个HashMap
<String pinNumber, int count>
,其中包含不同的pinNumber,告诉我List<Pin>
中有多少个不同的pinNumber以及每个pinNumber的数量。
所以我知道这样做的方法是:
List<Pin>
HashMap
是否已包含pinNumber的键值,并且:我想对Pin
对象中的每个字段执行相同的操作。
我相信应该有更简单的方法吗?
也许番石榴有更简单的东西?
答案 0 :(得分:3)
如果您有可能使用Java 8(并且因为您想要做的事情基本上听起来像是“分组依据”操作),这可以使用新的Stream API以优雅的方式解决(如用户vallismortis所示) ):
highest_start_date_to_be_found_of_this_element
输出:
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class Main {
public static void main(String[] args) {
List<Pin> pins = Arrays.asList(
new Pin("PIN-1", "T1", new Date()),
new Pin("PIN-1", "T2", new Date()),
new Pin("PIN-1", "T3", new Date()),
new Pin("PIN-2", "T2", new Date()),
new Pin("PIN-2", "T2", new Date()),
new Pin("PIN-3", "T2", new Date())
);
Map<String, Long> map = pins.stream().collect(groupingBy(Pin::getPinNumber, counting()));
System.out.println("map = " + map);
}
}
class Pin {
String pinNumber;
String pinType;
Date insertDate;
public Pin(String pinNumber, String pinType, Date insertDate) {
this.pinNumber = pinNumber;
this.pinType = pinType;
this.insertDate = insertDate;
}
public String getPinNumber() {
return pinNumber;
}
public String getPinType() {
return pinType;
}
public Date getInsertDate() {
return insertDate;
}
}
答案 1 :(得分:1)
你不需要番石榴。您可以使用标准Java 8功能。一种方法是使用流,但如果您需要计算多个字段的计数,则它们不适合。相反,您可以使用Map.merge
方法:
Map<String, Integer> byNumber = new HashMap<>();
Map<String, Integer> byType = new HashMap<>();
Map<Date, Integer> byInsertDate = new HashMap<>();
listOfPins.forEach(pin -> {
byNumber.merge(pin.getPinNumber(), 1, Integer::sum);
byType.merge(pin.getPinType(), 1, Integer::sum);
byInsertDate.merge(pin.getInsertDate(), 1, Integer::sum);
});
这样做的好处是它只能在listOfPins
上的一次迭代中完成,而对于流,你需要为每个字段一次传递。
答案 2 :(得分:0)
更简单的实施:
public static void main(String[] args) {
List<Pin> pinList = new ArrayList<Pin>();
// Add employee to list
pinList.add(new Pin("1234", "local", null));
pinList.add(new Pin("2345", "extra", null));
pinList.add(new Pin("3456", "extra", null));
pinList.add(new Pin("1234", "local", null));
Map<String, Integer> mapPinNumber = new HashMap<String, Integer>();
for (Pin pin : pinList) {
Integer cnt = mapPinNumber.get(pin.getPinNumber());
mapPinNumber.put(pin.getPinNumber(), (cnt == null) ? 1 : ++cnt);
}
printMap(mapPinNumber);
Map<String, Integer> mapPinType = new HashMap<String, Integer>();
for (Pin pin : pinList) {
Integer cnt = mapPinType.get(pin.getPinType());
mapPinType.put(pin.getPinType(), (cnt == null) ? 1 : ++cnt);
}
printMap(mapPinType);
}
private static void printMap(Map<String, Integer> map) {
String key;
int value;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
key = entry.getKey();
value = entry.getValue();
System.out.println(key + ": " + value);
}
}
答案 3 :(得分:0)
如果您不想依赖另一个库并希望保持与旧JVM的向后兼容性,这是一种可能的解决方案。它不是最好的,也不是最容易使用的,但确实有效。
<强> 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;
}
}
<强>输出强>
pinTypeFrequency typeB:1 typeA:2
pinNumberFrequency 80:1 50:2
insertDateFrequency Mon Jun 22 12:09:19 EDT 2015:3
仅供有趣和历史参考,Java 1.2版本:
<强> 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;
}
}
}