java学習 javaで単方向連結リストを実装

Javaで単方向連結リストを実装してエラトステネスの篩をかけてみた。

  • できるだけ汎用にしたいな → 総称クラスを使おう
  • イテレータがほしい → 自分で実装しよう
  • filterのための関数オブジェクトがほしい → じゃあその基底クラスを定義

とかしてる間に130行に。ちょっと複雑にしすぎちゃったかも。

出力

[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,]

ソース

/*
 * 単方向連結リストをGenericクラスで。
 * 関数型っぽくエラトステネスの篩をやる
 */
public class FooBar {
    public static void main(String[] args) {
        LinkList<Integer> lst = new LinkList<Integer>();
        for (int i = 2; i <= 100; i++)
            lst.add(i);
        for (int i = 2; i <= 10; i++)
            lst = lst.filter(new MultiplyFilter(i));
        System.out.println(lst);
    }
}

// リストの要素
class Node<type> {
    public type n;
    public Node<type> next;

    Node() {
        next = null;
    }

    public type value() {
        return n;
    }

    public String toString() {
        return n.toString();
    }
}

// 単方向連結リスト
class LinkList<type> {
    public Node<type> root;
    public Node<type> term;

    LinkList() {
        root = new Node<type>();
        term = new Node<type>();
        root.next = term;
    }

    public int len() {
        int length = 0;
        ListIterator<type> it = new ListIterator<type>(this);
        for (; !it.end(); it.next())
            length++;
        return length;
    }

    public void add(type n) {
        Node<type> node = new Node<type>();
        node.next = root.next;
        root.next = node;
        node.n = n;
    }

    public LinkList<type> filter(FilterFunctor<type> fun) {
        LinkList<type> lst = new LinkList<type>();
        ListIterator<type> it = new ListIterator<type>(this);
        for (; !it.end(); it.next())
            if (fun.call(it.value()))
                lst.add(it.value());
        return lst;
    }

    public String toString() {
        String s = "[";
        ListIterator<type> it = new ListIterator<type>(this);
        int i = 0;
        for (; !it.end(); it.next())
            s += it.toString() + ",";
        s += "]";
        return s;
    }
}

// LinkListのイテレータ
class ListIterator<type> {
    private Node<type> ref;
    private Node<type> term;

    ListIterator(LinkList<type> lst) {
        ref = lst.root.next;
        term = lst.term;
    }

    public type value() {
        return ref.n;
    }

    public boolean end() {
        return ref.equals(term);
    }

    public void next() {
        ref = ref.next;
    }

    public String toString() {
        return ref.toString();
    }
}

class FilterFunctor<argtype> {
    public boolean call(argtype arg) {
        return true;
    }
}

// 引数が自分を除く2以上の整数倍ならfalseを返す
class MultiplyFilter extends FilterFunctor<Integer> {
    private int n;

    MultiplyFilter(int n) {
        this.n = n;
    }

    public boolean call(Integer m) {
        return n == m.intValue() || m.intValue() % n != 0;
    }
}