在Java中组合两个列表

时间:2013-10-03 21:43:57

标签: java guava functional-java

我有两个参数数量相同的列表,我希望优雅 合并的方式(不是连接) 。

这是我当前(不太好)的方式(只是让你知道我想做什么)。

    List<Double> list1 = ... // init here
    List<Double> list2 = ... // init here
    Function<Double, Double, Double> myFunc = ... // init here

    List<Double> ret = new ArrayList<Double>(size);

    for (int n = 0; n < size; ++n)
    {
        ret.add(func.apply(list1.get(n),
                           list2.get(n)));
    }
    return ret;

interface Function <X, Y, Z>
{
    Z apply(X arg1, Y arg2);
}

是否有一些现有的助手可以让我做类似的事情:

Lists.combine(list1, list2, myFunction);

例如,假设我有两个整数列表,我有函数f(x, y) = x * y)

我希望结果列表是(x[i] * y[i])

的列表

具体而言,

list1 = {1, 2, 3, 4}
list2 = {2, 3, 4, 4}

result = {2, 6, 12, 15}

由于

2 个答案:

答案 0 :(得分:0)

主要的想法是创建一个方法,可以一次检索所有列表的所有索引,并将此结果返回到数组或集合中......您不必存储它们,只需要它们就可以了对它们的引用,您可以将它们作为参数传递给您的方法

这里有一些创建此类方法的方法,如果搜索返回的结果无效,您可以返回一个公共值:

private List<Double> firstList = new ArrayList<Double>();
private List<Double> secondList = new ArrayList<Double>();
private List<Double> thirdList = new ArrayList<Double>();
private static final double OUT_OF_BOUNDS = -1;

// just to initialize the arrays
private void initializeLists() {
    // dont pay attention to this
    for (double d1 = 0, d2 = 500, d3 = 5000; d1 < 50; d1++, d2++, d3++) {
        firstList.add(d1);
        secondList.add(d2);
        thirdList.add(d3);
    }
}

// create a method to retrieve data from both lists, and return it in an array or even
// a new list
private double[] apply(int index) {
    if (index < firstList.size() && index < secondList.size()) {
        if (index >= 0) {
            return new double[] { firstList.get(index), secondList.get(index) };
        }
    }
    return new double[] { OUT_OF_BOUNDS, OUT_OF_BOUNDS };
}

// you can pass those lists as parameters
private double[] apply(int index, List<Double> firstList, List<Double> secondList) {
    if (index < firstList.size() && index < secondList.size()) {
        if (index >= 0) {
            return new double[] { firstList.get(index), secondList.get(index) };
        }
    }
    return new double[] { OUT_OF_BOUNDS, OUT_OF_BOUNDS };
}

// you can even pass undefined number of lists (var-args)and grab there values at onnce
private double[] apply(int index, List<Double>... lists) {

    int listsSize = lists.length;

    if (index >= 0) {

        double[] search = new double[listsSize];

        for (int listIndex = 0; listIndex < listsSize; listIndex++) {

            List<Double> currentList = lists[listIndex];

            if (index < currentList.size()) {
                search[listIndex] = currentList.get(index);

            } else {
                search[listIndex] = OUT_OF_BOUNDS;
            }

        }
        return search;
    }

    double[] invalidSearch = new double[listsSize];
    for (int i = 0; i < listsSize; i++) {
        invalidSearch[i] = OUT_OF_BOUNDS;
    }
    return invalidSearch;

}

// now the work

public void combineLists() {
    initializeLists();
    double[] search = null;

    // search for index Zero in both lists
    search = apply(0);
    System.out.println(Arrays.toString(search));
    // result : [0.0, 500.0]

    // search for index One in both list parameters
    search = apply(1, firstList, secondList);
    System.out.println(Arrays.toString(search));
    // result : [1.0, 501.0]

    // search for index Two in var-args list parameters
    search = apply(2, firstList, secondList, thirdList);
    System.out.println(Arrays.toString(search));
    // result : [2.0, 502.0, 5002.0]


    // search for wrong index
    search = apply(800);
    System.out.println(Arrays.toString(search));
    // result : [-1.0, -1.0]

    // search for wrong index
    search = apply(800, firstList, secondList);
    System.out.println(Arrays.toString(search));
    // result : [-1.0, -1.0]


    // search for wrong index
    search = apply(800, firstList, secondList, thirdList);
    System.out.println(Arrays.toString(search));
    // result : [-1.0, -1.0,-1.0]

}

答案 1 :(得分:0)

这是一个解决方案。边界检查和所有错误处理省略:

public class Reducer
{
    public static <X, Y, Z> List<Z> reduce(List<X> list1, List<Y> list2, Function<X,Y,Z> func)
    {
        List<Z> result = new ArrayList<Z>();
        Iterator<X> i1 = list1.iterator();
        Iterator<Y> i2 = list2.iterator();
        for (int i=0; i<list1.size(); i++)
        {
            result.add(func.apply(i1.next(), i2.next()));
        }
        return result;
    }
}

public interface Function<X,Y,Z> {
    Z apply(X arg1, Y arg2);
}

以及如何使用

public static void main(String[] args)
{
    Function<Double, Double, Double> f = new Function<Double, Double, Double>() {
        @Override
        public Double apply(Double a1, Double a2) { return a1 * a2; }
    };

    List<Double> d1 = new ArrayList<Double>();
    List<Double> d2 = new ArrayList<Double>();
    List<Double> result = Reducer.reduce(d1, d2, f);
}