可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
In Java is there an object like a "Set" that can contain only unique string values, but also contain a count on the number of occurrences of the string value?
The idea is simple
With a data set ala...
A B B C C C
I'd like to add each line of text to a Set-like object. Each time that a non-unique text is added to the set I'd like to also have a numeric value associated with the set to display how many times it was added. So if I ran it on the above data set the output would be something like:
A : 1 B : 2 C : 3
any ideas?
回答1:
Map<String, Integer>
would be the best bet, to put in words what you want to do is to Map the amount of occurrences of a string. Basically have something like this:
public void add(String s) { if (map.containsKey(s)) { map.put(s, map.get(s) + 1); } else { map.put(s, 1); } }
回答2:
You want a "Bag", like the Bag in Apache Commons Collections or the Multiset in Google Collections. You can add the same value to it multiple times, and it'll record the counts of each value. You can then interrogate the counts.
You'd do something like this with Apache Commons' Bag:
Bag myBag = new HashBag(); myBag.add("Orange"); myBag.add("Apple", 4); myBag.add("Apple"); myBag.remove("Apple", 2); int apples = myBag.getCount("Apple"); // Should be 3. int kumquats = myBag.getCount("Kumquat"); // Should be 0.
And this with Google Collections' Multiset.
Multiset<String> myMultiset= HashMultiset.create(); myMultiset.add("Orange"); myMultiset.add("Apple", 4); myMultiset.add("Apple"); myMultiset.remove("Apple", 2); int apples = myMultiset.count("Apple"); // 3 int kumquats = myMultiset.count("Kumquats"); // 0
The problem with Apache Collections in general is that it isn't being very actively maintained, and it doesn't yet support Java Generics. To step into this gap, Google's written their own Collections which are extremely powerful. Be sure to evaluate Google Collections first.
Update: Google Collections also offers Multimap, a "collection similar to a Map, but which may associate multiple values with a single key".
回答3:
Yeap, not directly in the core, but can be built easily with a Map.
Here's a naive implementation:
import java.util.Map; import java.util.HashMap; public class SetLike { private Map<String, Integer> map = new HashMap<String,Integer>(); public void add( String s ) { if( !map.containsKey( s ) ){ map.put( s, 0 ); } map.put( s, map.get( s ) + 1 ); } public void printValuesAndCounts() { System.out.println( map ); } public static void main( String [] args ){ String [] data = {"A","B","B","C","C","C"}; SetLike holder = new SetLike(); for( String value : data ) { holder.add( value ); } holder.printValuesAndCounts(); } }
Test it
$ javac SetLike.java $ java SetLike {A=1, C=3, B=2}
Of course you can improve it much more. You can implement the Set interface, or a List, or a Collection, etc, you can add the iterators, implement Iterable and so on, it depends on what you want and what you need.
回答4:
This will be helpful..
List<String> myList=new ArrayList<String>(); myList.add("A"); myList.add("B"); myList.add("B"); myList.add("C"); myList.add("C"); myList.add("C"); Set<String> set=new HashSet<String>(myList); for (String value : set) { int occurance=Collections.frequency(myList, value); System.out.println(value +" occur "+occurance + " times "); }
Result :
A occur 1 times B occur 2 times C occur 3 times