问题
我有一个ArrayList
,一个Java的Collection类,如下所示:
ArrayList<String> animals = new ArrayList<String>();
animals.add("bat");
animals.add("owl");
animals.add("bat");
animals.add("bat");
如你所见,animals``ArrayList
包含3bat
个元素和一个owl
元素。我想知道Collection框架中是否有任何API返回数量为2656537184的出现次数,或者是否有另一种方法来确定出现次数。
我发现Google的CollectionMultiset
有一个API,可以返回元素的总出现次数。但这只与JDK 1.5兼容。我们的产品目前是JDK 1.6,所以我不能使用它。
#1 热门回答(276 赞)
我很确定Collections中的静态频率方法会派上用场:
int occurrences = Collections.frequency(animals, "bat");
无论如何我就是这样做的。我很确定这是jdk 1.6直线上升。
#2 热门回答(59 赞)
在Java 8中:
Map<String, Long> counts =
list.stream().collect(Collectors.groupingBy(e -> e, Collectors.counting()));
#3 热门回答(22 赞)
这表明,为什么对于"Refer to objects by their interfaces"很重要,如Effective Java中所述。
如果你编写实现代码并使用ArrayList,比如代码中的50个位置,当你找到一个计算项目的良好"List"实现时,你将不得不更改所有这50个地方,并且可能你必须打破你的代码(如果你只使用它没有什么大不了的,但如果它被其他人使用,你也会破坏他们的代码)
通过对接口进行编程,你可以将这50个位置保持不变,并将实现从ArrayList替换为"CountItemsList"(例如)或其他类。
下面是一个关于如何写这个的基本样本。这只是一个样本,一个生产就绪列表将是多更复杂。
import java.util.*;
public class CountItemsList<E> extends ArrayList<E> {
// This is private. It is not visible from outside.
private Map<E,Integer> count = new HashMap<E,Integer>();
// There are several entry points to this class
// this is just to show one of them.
public boolean add( E element ) {
if( !count.containsKey( element ) ){
count.put( element, 1 );
} else {
count.put( element, count.get( element ) + 1 );
}
return super.add( element );
}
// This method belongs to CountItemList interface ( or class )
// to used you have to cast.
public int getCount( E element ) {
if( ! count.containsKey( element ) ) {
return 0;
}
return count.get( element );
}
public static void main( String [] args ) {
List<String> animals = new CountItemsList<String>();
animals.add("bat");
animals.add("owl");
animals.add("bat");
animals.add("bat");
System.out.println( (( CountItemsList<String> )animals).getCount( "bat" ));
}
}
这里应用的OO原则:继承,多态,抽象,封装。