001/*
002 * $Id$
003 */
004
005package edu.jas.util;
006
007
008import java.lang.Iterable;
009import java.util.ArrayList;
010import java.util.LinkedList;
011import java.util.List;
012import java.util.Iterator;
013
014import edu.jas.structure.Element;
015import edu.jas.structure.UnaryFunctor;
016
017
018/**
019 * List utilities. For example map functor on list elements.
020 * @author Heinz Kredel
021 */
022
023public class ListUtil {
024
025
026    //private static final Logger logger = LogManager.getLogger(ListUtil.class);
027
028
029    // private static final boolean debug = logger.isDebugEnabled(); 
030
031
032    /**
033     * Map a unary function to the list.
034     * @param f evaluation functor.
035     * @return new list elements f(list(i)).
036     */
037    public static <C extends Element<C>, D extends Element<D>> List<D> map(List<C> list, UnaryFunctor<C, D> f) {
038        if (list == null) {
039            return null;
040        }
041        List<D> nl;
042        if (list instanceof ArrayList) {
043            nl = new ArrayList<D>(list.size());
044        } else if (list instanceof LinkedList) {
045            nl = new LinkedList<D>();
046        } else {
047            throw new RuntimeException("list type not implemented");
048        }
049        for (C c : list) {
050            D n = f.eval(c);
051            nl.add(n);
052        }
053        return nl;
054    }
055
056
057    /**
058     * Tuple from lists.
059     * @param A list of lists.
060     * @return new list with tuples (a_1,...,an) with ai in Ai,
061     *         i=0,...,length(A)-1.
062     */
063    public static <C> List<List<C>> tupleFromList(List<List<C>> A) {
064        if (A == null) {
065            return null;
066        }
067        List<List<C>> T = new ArrayList<List<C>>(A.size());
068        if (A.size() == 0) {
069            return T;
070        }
071        if (A.size() == 1) {
072            List<C> Ap = A.get(0);
073            for (C a : Ap) {
074                List<C> Tp = new ArrayList<C>(1);
075                Tp.add(a);
076                T.add(Tp);
077            }
078            return T;
079        }
080        List<List<C>> Ap = new ArrayList<List<C>>(A);
081        List<C> f = Ap.remove(0);
082        List<List<C>> Tp = tupleFromList(Ap);
083        //System.out.println("Tp = " + Tp);
084        for (C a : f) {
085            for (List<C> tp : Tp) {
086                List<C> ts = new ArrayList<C>();
087                ts.add(a);
088                ts.addAll(tp);
089                T.add(ts);
090            }
091        }
092        return T;
093    }
094
095
096    /**
097     * Create a list of given length and content.
098     * @param n length of new list
099     * @param e object to be filled in
100     * @return list (e, ..., e) of length n
101     */
102    public static <C> List<C> fill(int n, C e) {
103        List<C> r = new ArrayList<C>(n);
104        for (int m = 0; m < n; m++) {
105            r.add(e);
106        }
107        return r;
108    }
109
110
111    /**
112     * Test two iterables for equal contents and sequence.
113     * @param a iterable
114     * @param b iterable
115     * @return true, if a equals b in sequence and content, else false.
116     */
117    public static <C> boolean equals(Iterable<C> a, Iterable<C> b) {
118        Iterator<C> ai = a.iterator();
119        Iterator<C> bi = b.iterator();
120        while (ai.hasNext() && bi.hasNext()) {
121            C aa = ai.next();
122            C ba = bi.next();
123            if (!aa.equals(ba)) {
124                System.out.println("aa != ba: " + aa + " != " + ba);
125                return false;
126            }
127        }
128        if (ai.hasNext()) {
129            System.out.println("aa: " + ai.next());
130            return false;
131        }
132        if (bi.hasNext()) {
133            System.out.println("ba: " + bi.next());
134            return false;
135        }
136        return true;
137    }
138
139}