我有两个参数数量相同的列表,我希望优雅 合并的方式(不是连接) 。
这是我当前(不太好)的方式(只是让你知道我想做什么)。
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}
由于
答案 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);
}