ForwardingMultiset

Google collectionsForwarding系のForwardingMultisetは、どう使ったらいいかいろいろ考えて、以下のようなコードを作ってみました。
Multisetは、ヒストグラムとかするときに便利ですが、平均(追加回数を数えて置いて後で合計から割る)や最大値もあると必要あるかと思いました。
(詳しくはページ後ろの添付を見てみてください。)
表とかの順番がはっきりしている場合は、int配列とか使った方が速いケースがほとんどでしょうけどね。
  • CounterMultiset - 追加された回数を記録する
  • MaxMultiset - 追加された最大値を保存する
  • MinMultiset  - 追加された最小値を保存する
こういう風に重ねて使います。これだと、とってもデコレーションパターンぽく見えますね。

Multiset<String> mset=LinkedHashMultiset.create();
CounterMultiSet<String> counter=new CounterMultiSet<String>(mset);
MaxMultiSet<String> max=new MaxMultiSet<String>(counter);
MinMultiSet<String> min=new MinMultiSet<String>(max);



MultisetTest

/*
 * 
 * Copyright 2010 akjava.com 

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 * 
 */
package gc;

import com.google.common.collect.HashMultiset;
import com.google.common.collect.LinkedHashMultiset;
import com.google.common.collect.Multiset;

import static java.lang.System.currentTimeMillis;

public class MultisetTest {

public static void main(String argv[]){
//Multiset<String> mset=HashMultiset.create();
Multiset<String> mset=LinkedHashMultiset.create();
CounterMultiSet<String> counter=new CounterMultiSet<String>(mset);
for(int j=0;j<10;j++){
for(int i=0;i<10;i++){
counter.add("hello"+i);
}
}
for(String label:mset.elementSet()){
System.out.println(label);
}
counter.clear();
MaxMultiSet<String> max=new MaxMultiSet<String>(counter);
MinMultiSet<String> min=new MinMultiSet<String>(max);
//becareful large number make java.lang.IllegalArgumentException:too many occurrences: 2147516415
long t=currentTimeMillis();
for(int j=0;j<10;j++){
min.clear();
for(int i=1;i<=50000;i++){
min.add("hello",i+1);
}
}
System.out.println(currentTimeMillis()-t+":ms"); 
//hash 192ms
System.out.println(counter.count("hello")+","+counter.countCounter("hello"));
System.out.println(max.count("hello")+","+max.countMax("hello"));
System.out.println(min.count("hello")+","+min.countMin("hello"));
}
}



CounterMultiset

カウンターマルチセットの場合、内部に別のMultisetを持って、追加されたら数値に関わらず増やすことで追加回数を記録します。

public int add(T element, int occurrences) {
counter.add(element);
return super.add(element, occurrences);
}


MaxMultiset


Maxマルチセットの場合は、数値の追加時に、過去の最大値と比べて保存します。

public int add(T element, int occurrences) {
if(occurrences>max.count(element)){
max.setCount(element, occurrences);
}
return super.add(element, occurrences);
}


MinMultiset


Minの場合、存在しない場合に気をつけて最小値を保存しています。

public int add(T element, int occurrences) {
if(occurrences<min.count(element)|| !min.contains(element)){
min.setCount(element, occurrences);
}
return super.add(element, occurrences);
}



ċ
CounterMultiSet.java
(1k)
aki akj,
2010/02/14 4:07
ċ
MaxMultiSet.java
(2k)
aki akj,
2010/02/14 4:07
ċ
MinMultiSet.java
(2k)
aki akj,
2010/02/14 4:07
ċ
MultisetTest.java
(2k)
aki akj,
2010/02/14 4:07
Comments