    001/*
    002 * Copyright (c) 2009 The openGion Project.
    003 *
    004 * Licensed under the Apache License, Version 2.0 (the "License");
    005 * you may not use this file except in compliance with the License.
    006 * You may obtain a copy of the License at
    007 *
    008 *     http://www.apache.org/licenses/LICENSE-2.0
    009 *
    010 * Unless required by applicable law or agreed to in writing, software
    011 * distributed under the License is distributed on an "AS IS" BASIS,
    012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
    013 * either express or implied. See the License for the specific language
    014 * governing permissions and limitations under the License.
    015 */
    016package org.opengion.fukurou.util;
    017
    018import java.util.LinkedHashSet;
    019import java.util.Collections;
    020import java.util.Iterator;
    021import java.util.function.BiConsumer;
    022
    023/**
    024 * ArraySet.java は、LinkedHashSet を継承した、Setオブジェクトです。
    025 *
    026 * 初期オブジェクト作成のための、引数に、配列(可変長配列)を渡せるようにしています。
    027 * また、Iterable#forEach( Consumer ) で、ループカウンタが使えるように、新しく、
    028 * BiConsumer を引数に取る forEach( int , BiConsumer ) メソッドを用意しています。
    029 *
    030 * @og.rev 6.4.3.4 (2016/03/11) 新規追加
    031 *
    032 * @version  6.4
    033 * @author       Kazuhiko Hasegawa
    034 * @since    JDK8.0,
    035 */
    036public class ArraySet<E> extends LinkedHashSet<E> {
    037        /** このプログラムのVERSION文字列を設定します。   {@value} */
    038        private static final String VERSION = "6.4.3.4 (2016/03/11)" ;
    039        private static final long serialVersionUID = 643420160311L ;
    040
    041        /**
    042         * LinkedHashSet を継承した、Setオブジェクトです。
    043         *
    044         * 初期オブジェクト作成のための、引数に、配列を渡せるようにしています。
    045         *
    046         * @og.rev 6.4.3.4 (2016/03/11) 新規追加
    047         *
    048         * @param       elements 初期値として設定する可変長配列
    049         */
    050        @SuppressWarnings({"unchecked", "varargs"})
    051        public ArraySet( final E... elements ) {
    052                super();
    053                Collections.addAll( this, elements );
    054        }
    055
    056        /**
    057         * Iterable#forEach( Consumer ) で、引数に、ループカウンタを使用できるメソッドです。
    058         *
    059         * ラムダ式から参照されるローカル変数は、finalまたは事実上のfinalである必要があります。
    060         * ところが、訳あって、ループカウンタが必要です。そこで、内部処理として、ループカウンタを
    061         * 用意しておき、それを、ラムダ式の引数として渡す方法で、対応します。
    062         * 一覧の処理は、内部で、Iterator#hasNext() と、Iterator#next() を使用しているため、
    063         * インスタンスレベルのsynchronized ブロックを使用しています。
    064         *
    065         * @og.rev 6.4.3.4 (2016/03/11) 新規追加
    066         *
    067         * @param       cnt カウンタの初期値
    068         * @param       action 各要素に対して実行されるアクション( カウンタ、内部オブジェクト )
    069         * @see         Iterable#forEach( Consumer )
    070         */
    071        public void forEach( final int cnt , final BiConsumer<Integer ,E> action ) {
    072                int i = cnt;
    073
    074                synchronized( this ) {
    075                        final Iterator<E> ite = iterator();
    076                        while( ite.hasNext() ) {
    077                                action.accept( i++ , ite.next() );
    078                        }
    079                }
    080        }
    081}