从 Java 列表结构中选择基数最低的元素
Choose elements with lowest cardinality from Java List structure
一个简单的问题,但在 google 上找不到答案。因为我通常使用 SQL,所以我习惯于像这样访问基于集合的操作:
select Q, qCount
from (
select Q, qCount, min(qCount) over () as minQCount
from (
select Q, count(*) as qCount
from table_A
group by Q
)
)
where qCount = minQCount
这会从 table 中找到所有 Q 值,这些值在一组不同的 Q 值中具有最低的基数。
对于 Java 列表,是否有既定的有效方法?说:
List<Q> listOfQ //gets populated with different objects of Q
//objects of Q can represent the same value through an overridden equals()
//get each object from Q for which the cardinality of the value it represents
//is the lowest amongst the distinct values in the list
一个简单的例子是:
List<Integer> list = new ArrayList<Integer>();
list.addAll(Arrays.asList(new Integer[] {1,1,1,2,2,3,3,3,4,4,4,4,5,5}));
//want to retrieve {2,2,5,5}
//would also be nice to easily retrieve a map with {k:2 v:2, k:5 v:2}
//this being the equivalent of the SQL query above
谢谢!
Hashtable<String, Integer> ht = new Hashtable<String, Integer>() ;
for(Integer i : list){
if(ht.contain(i+""){
Integer v = ht.get(i+"") + 1 ;
}else{
ht.put(i+"" , 1) ;
}
}
// now we need order it
TreeMap<String, Integer> tm= new TreeMap<Integer, String>(ht);
现在树图将按键和值排序
考虑使用 GUAVA 的 Multiset。
上面可以用count(key)
方法得到号码
private static <K> Map<K, Integer> getElementsWithLessCardinality(
List<K> list) {
Map<K, Integer> map = new TreeMap<K, Integer>(); //or HashMap
Map<K, Integer> res = new TreeMap<K, Integer>();
Integer min = null;
for (K listElem : list) {
if (map.containsKey(listElem)) {
map.put(listElem, map.get(listElem) + 1);
} else {
map.put(listElem, 1);
}
}
for (Entry<K, Integer> pair : map.entrySet()) {
K key = pair.getKey();
Integer value = pair.getValue();
if (min == null) {
// Initial state
min = value;
res.put(key, value);
} else if (min.equals(pair.getValue())) {
res.put(key, value);
} else if (value.compareTo(min) == -1) {
res.clear();
min = value;
res.put(key, value);
}
}
return res;
}
我想你可以这样做:
-首先你得到一张完整的地图。
-然后你找基数小的放到另外一个map里。
请注意,此解决方案使用参数类型,因此您可以在需要计算任何类型的对象时使用它。 (但要确保 compareTo()、equals() 和 hashCode() 在 class K 中得到很好的实现)
使用 apache 公共集合:
final List<Integer> list = Arrays.asList(new Integer[]{1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5});
final Map<Integer, Integer> cardinalityMap = CollectionUtils.getCardinalityMap(list);
final int minCardinality = Collections.min(cardinalityMap.values());
System.out.println("min cardinality: " + minCardinality);
for (final Map.Entry<Integer, Integer> entry: cardinalityMap.entrySet()) {
if (minCardinality == entry.getValue()) {
System.out.println("key: " + entry.getKey());
}
}
控制台输出:
min cardinality: 2
key: 2
key: 5
一个简单的问题,但在 google 上找不到答案。因为我通常使用 SQL,所以我习惯于像这样访问基于集合的操作:
select Q, qCount
from (
select Q, qCount, min(qCount) over () as minQCount
from (
select Q, count(*) as qCount
from table_A
group by Q
)
)
where qCount = minQCount
这会从 table 中找到所有 Q 值,这些值在一组不同的 Q 值中具有最低的基数。
对于 Java 列表,是否有既定的有效方法?说:
List<Q> listOfQ //gets populated with different objects of Q
//objects of Q can represent the same value through an overridden equals()
//get each object from Q for which the cardinality of the value it represents
//is the lowest amongst the distinct values in the list
一个简单的例子是:
List<Integer> list = new ArrayList<Integer>();
list.addAll(Arrays.asList(new Integer[] {1,1,1,2,2,3,3,3,4,4,4,4,5,5}));
//want to retrieve {2,2,5,5}
//would also be nice to easily retrieve a map with {k:2 v:2, k:5 v:2}
//this being the equivalent of the SQL query above
谢谢!
Hashtable<String, Integer> ht = new Hashtable<String, Integer>() ;
for(Integer i : list){
if(ht.contain(i+""){
Integer v = ht.get(i+"") + 1 ;
}else{
ht.put(i+"" , 1) ;
}
}
// now we need order it
TreeMap<String, Integer> tm= new TreeMap<Integer, String>(ht);
现在树图将按键和值排序
考虑使用 GUAVA 的 Multiset。
上面可以用count(key)
方法得到号码
private static <K> Map<K, Integer> getElementsWithLessCardinality(
List<K> list) {
Map<K, Integer> map = new TreeMap<K, Integer>(); //or HashMap
Map<K, Integer> res = new TreeMap<K, Integer>();
Integer min = null;
for (K listElem : list) {
if (map.containsKey(listElem)) {
map.put(listElem, map.get(listElem) + 1);
} else {
map.put(listElem, 1);
}
}
for (Entry<K, Integer> pair : map.entrySet()) {
K key = pair.getKey();
Integer value = pair.getValue();
if (min == null) {
// Initial state
min = value;
res.put(key, value);
} else if (min.equals(pair.getValue())) {
res.put(key, value);
} else if (value.compareTo(min) == -1) {
res.clear();
min = value;
res.put(key, value);
}
}
return res;
}
我想你可以这样做:
-首先你得到一张完整的地图。
-然后你找基数小的放到另外一个map里。
请注意,此解决方案使用参数类型,因此您可以在需要计算任何类型的对象时使用它。 (但要确保 compareTo()、equals() 和 hashCode() 在 class K 中得到很好的实现)
使用 apache 公共集合:
final List<Integer> list = Arrays.asList(new Integer[]{1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5});
final Map<Integer, Integer> cardinalityMap = CollectionUtils.getCardinalityMap(list);
final int minCardinality = Collections.min(cardinalityMap.values());
System.out.println("min cardinality: " + minCardinality);
for (final Map.Entry<Integer, Integer> entry: cardinalityMap.entrySet()) {
if (minCardinality == entry.getValue()) {
System.out.println("key: " + entry.getKey());
}
}
控制台输出:
min cardinality: 2
key: 2
key: 5