    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.Collection;                                                                                    // 7.0.1.1 (2018/10/22)
    020import java.util.Collections;
    021import java.util.Iterator;
    022import java.util.function.BiConsumer;
    023
    024import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE;              // 7.0.1.1 (2018/10/22)
    025
    026/**
    027 * ArraySet.java は、LinkedHashSet を継承した、Setオブジェクトです。
    028 *
    029 * 初期オブジェクト作成のための、引数に、配列(可変長配列)を渡せるようにしています。
    030 * また、Iterable#forEach( Consumer ) で、ループカウンタが使えるように、新しく、
    031 * BiConsumer を引数に取る forEach( int , BiConsumer ) メソッドを用意しています。
    032 *
    033 * @og.rev 6.4.3.4 (2016/03/11) 新規追加
    034 *
    035 * @version  6.4
    036 * @author       Kazuhiko Hasegawa
    037 * @since    JDK8.0,
    038 */
    039public class ArraySet<E> extends LinkedHashSet<E> {
    040        /** このプログラムのVERSION文字列を設定します。   {@value} */
    041        private static final String VERSION = "7.0.1.1 (2018/10/22)" ;
    042        private static final long serialVersionUID = 701120181022L ;
    043
    044        /**
    045         * LinkedHashSet を継承した、Setオブジェクトです。
    046         *
    047         * 初期オブジェクト作成のための、引数に、配列を渡せるようにしています。
    048         *
    049         * @og.rev 7.0.1.1 (2018/10/22) 新規追加
    050         *
    051         * @param       elements 初期値として設定する可変長配列
    052         */
    053        @SuppressWarnings({"unchecked", "varargs"})
    054        public ArraySet( final E... elements ) {
    055                super();
    056                Collections.addAll( this, elements );
    057        }
    058
    059        /**
    060         * 他のCollectionオブジェクトを追加します。
    061         *
    062         * @og.rev 6.4.3.4 (2016/03/11) 新規追加
    063         *
    064         * @param       collect Collectionオブジェクトの可変長配列
    065         * @return      自分自身
    066         */
    067        @SuppressWarnings({"unchecked"})
    068        public ArraySet<E> addAll( final Collection<E>... collect ) {
    069                if( collect != null && collect.length > 0 ) {
    070                        for( final Collection<E> obj : collect ) {
    071                                super.addAll( obj );
    072                        }
    073                }
    074                return this ;
    075        }
    076
    077        /**
    078         * Iterable#forEach( Consumer ) で、引数に、ループカウンタを使用できるメソッドです。
    079         *
    080         * ラムダ式から参照されるローカル変数は、finalまたは事実上のfinalである必要があります。
    081         * ところが、訳あって、ループカウンタが必要です。そこで、内部処理として、ループカウンタを
    082         * 用意しておき、それを、ラムダ式の引数として渡す方法で、対応します。
    083         * 一覧の処理は、内部で、Iterator#hasNext() と、Iterator#next() を使用しているため、
    084         * インスタンスレベルのsynchronized ブロックを使用しています。
    085         *
    086         * @og.rev 6.4.3.4 (2016/03/11) 新規追加
    087         *
    088         * @param       cnt カウンタの初期値
    089         * @param       action 各要素に対して実行されるアクション( カウンタ、内部オブジェクト )
    090         * @see         Iterable#forEach( Consumer )
    091         */
    092        public void forEach( final int cnt , final BiConsumer<Integer ,E> action ) {
    093                int i = cnt;
    094
    095                synchronized( this ) {
    096                        final Iterator<E> ite = iterator();
    097                        while( ite.hasNext() ) {
    098                                action.accept( i++ , ite.next() );
    099                        }
    100                }
    101        }
    102
    103        /**
    104         * このオブジェクトの内部表現を、文字列にして返します。
    105         * 内部ｵﾌﾞｼﾞｪｸﾄの toString() を順番に呼んで、カンマで連結した文字列を返します。
    106         *
    107         * @og.rev 7.0.1.1 (2018/10/22) 新規追加
    108         *
    109         * @return  引数に対する値
    110         * @og.rtnNotNull
    111         */
    112        @Override
    113        public String toString() {
    114                final StringBuilder buf = new StringBuilder( BUFFER_MIDDLE );
    115
    116                synchronized( this ) {
    117                        final Iterator<E> ite = iterator();
    118                        while( ite.hasNext() ) {
    119                                buf.append( ite.next() ).append( ',' );
    120                        }
    121                }
    122
    123                if( buf.length() > 0 ) { buf.setLength( buf.length()-1 ); }             // 最後のカンマを削除
    124
    125                return buf.toString();
    126        }
    127}