Java8 StreamでWicket ListViewセル結合

昨日書いた groupingBy の利用として、HTML-tableタグ rowspan結合をサンプルとして作ってみました。

keyでグルーピング可能な任意オブジェクトリストを受け取って最終目的は以下のような表を作ることです。

f:id:posturan:20160313173540j:plain


Wicket ListView でこの表を作ります。

対象のオブジェクトのクラス宣言は、以下のとおりです。
public class Author{
   public String level;
   public String name;
   public Author(String level, String name){
      this.level = level;
      this.name = name;
   }
}

// サンプルとして用意するSQLクエリで抽出する代わりの Authorリスト生成
private List<Author< createAuthors(){
   return Arrays.asList(
      new Author("A", "あああ"),
      new Author("A", "いいい"),
      new Author("D", "ききき"),
      new Author("A", "ううう"),
      new Author("B", "えええ"),
      new Author("C", "おおお"),
      new Author("F", "けけけ"),
      new Author("E", "くくく"),
      new Author("C", "かかか"),
      new Author("F", "こここ")
   );
}

とにかく、SQL実行の代わりで、ソートもされてなくてバラバラに渡されるものとします。

List<Author> authors = createAuthors();

// rowspan 結合する1列目をグルーピングしてカウントをリストマップを生成して
// ListView に、グルーピングした結果のリストの結合を渡します。


final Map<String, Long> groupCounters = authors.stream().collect(Collectors.groupingBy(t->t.levelCollectors.counting()));
Map<String, List<Author>> mapAuthors = authors.stream().collect(Collectors.groupingBy(t->t.levelCollectors.mapping(u->u, Collectors.toList())));

queue(new ListView<Author>("listview", mapAuthors.keySet().stream().flatMap(k->mapAuthors.get(k).stream()).collect(Collectors.toList())){
   long count = 0;
   @Override
   protected void populateItem(final ListItem<Author> item){
      Author author = item.getModelObject();
      item.add(new Label("level", author.level){
         @Override
         protected void onComponentTag(ComponentTag tag){

            super.onComponentTag(tag);
            count++;
            long groupCount = groupCounters.get(author.level);
            if (count==1){
               if (groupCount > 1){
                  tag.put("rowspan", Long.toString(groupCount));
               }else{
                  count = 0;
               }
            }else{
               tag.put("style", "display: none");
               if (groupCount==count){
                  count = 0;
               }
            }
         }
      });
      item.add(new Label("name", author.name));
   }
});