localdisk

PHP とか Java とか Web とか好きなことを書きます。

PHPでJava風のArrayListを作ってみた

前回のエントリJava 風の HashMap を作ってみました。hash だけだと片手落ちなので今回は ArrayList を作ってみました。
で、こういったソースを手軽における場所を探してたところ id:juno さんに

ちょっとしたコード置き場には http://gist.github.com/ とか便利ですよ。

PHPでJava風のHashMapを作ってみた - localdisk

とアドバイスいただきました。最近流行っているのは知っていたのですが、触る機会がないので「これを期に!」と Git に挑戦してみたのですが Windows にはろくな Git クライアントがないことが判明。ならばということで Mercurial に現在挑戦中です。上手くいったら Free source code hosting for Git and Mercurial by Bitbucket にUPする予定です。
と、いうことで以下ソース

<?php
/**
 * JavaのArrayListをPHPで実装してみた
 */
class ArrayList extends ArrayObject {
    /**
     * コンストラクタ
     *
     * @param array $array
     */
    public function __construct($array = array()) {
        parent::__construct($array, ArrayObject::ARRAY_AS_PROPS);
    }
    /**
     * リストの最後に、指定された要素を追加します
     *
     * @param  mixed $e
     * @return ArrayList
     */
    public function add($e) {
        parent::append($e);
        return $this;
    }
    /**
     * 指定されたリスト内のすべての要素をリストの最後に追加します
     *
     * @param  ArrayList $c
     * @return ArrayList
     */
    public function addAll(ArrayList $c) {
        foreach ($c as $v) {
            parent::append($v);
        }
        return $this;
    }
    /**
     * リストからすべての要素を削除します
     * 
     * @return ArrayList
     */
    public function clear() {
        foreach ($this as $k => $v) {
            parent::offsetUnset($k);
        }
        return $this;
    }
    /**
     * リストに指定の要素がある場合に true を返します
     * 
     * @param  mixed $o
     * @return boolean
     */
    public function contains($o) {
        foreach ($this as $v) {
            if ($o === $v) {
                return true;
            }
        }
        return false;
    }
    /**
     * リスト内の指定された位置にある要素を返します
     *
     * @param  intger $index
     * @return mixed
     */
    public function get($index) {
        return parent::offsetGet($index);
    }
    /**
     * 指定された要素がリスト内で最初に検出された位置のインデックスを返します
     * 
     * @param  mixed $o
     * @return integer
     */
    public function indexOf($o) {
        foreach ($this as $k => $v) {
            if ($o === $v) {
                return $k;
            }
        }
        return -1;
    }
    /**
     * 指定された要素がリスト内で最後に検出された位置のインデックスを返します
     *
     * @param  mixed $o
     * @return integer
     */
    public function lastIndexOf($o) {
        $size = parent::count();
        for ($i = $size - 1; $i >= 0; $i--) {
            if ($o === parent::offsetGet($i)) {
                return $i;
            }
        }
        return -1;
    }
    /**
     * リストに要素がない場合に true を返します
     *
     * @return boolean
     */
    public function isEmpty() {
        if (parent::count() === 0) {
            return true;
        }
        return false;
    }
    /**
     * リストの要素を削除します
     * 引数 $index が int の場合引数で指定された位置の要素を削除します
     * 引数が int 以外の場合、指定された要素がリストに存在すれば、その最初の要素を削除します
     * 
     * @param  integer|mixed $index
     * @return ArrayList
     */
    public function remove($index) {
        if (is_integer($index)) {
            parent::offsetUnset($index);
        } else {
            $i = $this->indexOf($index);
            parent::offsetUnset($i);
        }
        return $this;
    }
    /**
     * リストの指定された位置にある要素を、指定された要素で置き換えます
     * インデックスの範囲外の場合リストを追加します
     * 
     * @param  integer $index
     * @param  mixed   $element
     * @return ArrayList
     */
    public function set($index, $element = null) {
        if (!is_integer($index)) {
            throw new InvalidArgumentException('invalid argment $index');
        }
        parent::offsetSet($index, $element);
        return $this;
    }
    /**
     * リスト内にある要素の数を返します
     * 
     * @return integer
     */
    public function size() {
        return parent::count();
    }
    /**
     * このリスト内の要素を適切な順序で繰り返し処理する反復子を返します
     * 
     * @return Iterator
     */
    public function iterator() {
        return parent::getIterator();
    }
    /**
     * リストを配列にして返します
     *
     * @return array
     */
    public function toArray() {
        $i = parent::getIterator();
        return iterator_to_array($i);
    }
}