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; } }