【发布时间】:2021-01-26 11:30:24
【问题描述】:
我正在尝试创建一个函数,它提供一个数组列表和两个整数数组作为输入:
public boolean[] checkMatching(ArrayList<String[]> items, Integer[] arr1, Integer[] arr2){...}
检查是否至少有两个项目的 arr1 索引值相同,但 arr2 的索引值不同。例如:
ArrayList<String[]> items = new ArrayList<String[]>();
//All arrays in items have the same number of elements
items.add(new String[]{"B","2","5","6","W"}); //item1
items.add(new String[]{"A","2","5","6","X"}); //item2
items.add(new String[]{"A","2","1","3","Y"}); //item3
items.add(new String[]{"N","F","1","2","W"}); //item4
items.add(new String[]{"A","2","5","6","V"}); //item5
int[] arr1 = new int[] {1,2};
int[] arr2 = new int[] {0,3,4};
boolean[] results = checkMatching(items, arr1, arr2)
在前面的例子中,函数应该返回:
[-1, 1, -1]
因为 item1、item2 和 item5 对于 arr1 的索引共享相同的值,而它们索引 0,4 具有不同的值,索引 3 具有相同的值。
请注意,该方法返回 3 个整数,因为在 arr2 中有 3 个索引。因此,每个布尔值都引用 arr2 中的一个索引。
这可能是一个利用函数式编程的解决方案:
public class Temp2 {
public static void main(String[] args) {
ArrayList<String[]> items = null;
items = new ArrayList<String[]>();
items.add(new String[]{"B","2","5","6","W"}); //item1
items.add(new String[]{"A","2","5","6","X"}); //item2
items.add(new String[]{"A","2","1","3","Y"}); //item3
items.add(new String[]{"N","F","1","2","W"}); //item4
items.add(new String[]{"A","2","5","6","V"}); //item5
int[] arr1 = new int[] {1,2};
int[] arr2 = new int[] {0,3,4};
Temp2 tmp = new Temp2();
int[] results = tmp.checkMatching(items, arr1, arr2);
for(int k = 0; k < 5; k++) {
System.out.print(results[k]+"|");
}
System.out.println();
}
public int[] checkMatching(ArrayList<String[]> items, int[] arr, int[] arr2){
int maxIndex = 4;
Function<String[], String> compositeKey = el -> getFunctionParametersTest(el, arr);
Optional<int[]> map = items.stream()
.collect(Collectors.groupingBy(compositeKey, Collectors.toList())).entrySet().stream()
.filter(entry -> entry.getValue().size() > 1)
.map(entry -> {
List<String[]> values = entry.getValue();
int[] generalResponse = new int[maxIndex+1];
if (values.size() > 1) {
for (int i = 0; i < arr2.length; i++) {
String tmp = "";
int risposta = -2;
for (String[] e : values) {
if(tmp.length() > 0) {
if (tmp.compareTo(e[arr2[i]]) != 0) {
risposta = -1;
break;
} else {
risposta = 1;
}
}
else {
tmp = e[arr2[i]];
}
}
generalResponse[i] = risposta;
}
}
return generalResponse;
}).reduce((a, b) -> {
int[] arrLocal = a;
int[] arrarrLocal2 = b;
int[] sum = new int[a.length];
for (int k = 0; k < arrLocal.length; k++) {
if (arrLocal[k] == -1 || arrarrLocal2[k] == -1) {
sum[k] = -1;
} else if (arrLocal[k] >= arrarrLocal2[k]) {
sum[k] = arrLocal[k];
} else if (arrLocal[k] < arrarrLocal2[k]) {
sum[k] = arrarrLocal2[k];
}
}
return sum;
});
int[] finalresults = null;
if (map.isEmpty() == false) {
finalresults = map.get();
} else {
finalresults = new int[maxIndex+1];
for (int k = 0; k < maxIndex; k++) {
finalresults[k] = 1;
}
}
return finalresults;
}
public String getFunctionParametersTest(String[] item, int[] arr) {
String values = "";
for (Integer i : arr) {
values += item[i] + "-";
}
return values;
}
}
但是效率不是很高,尤其是在物品数量很大的时候。有谁能帮助我吗?我正在尝试开发一个性能非常好的解决方案,但我不知道是否有比函数式编程更快的解决方案。
【问题讨论】:
-
如果应该返回布尔数组,返回
[-1, 1, -1]是什么意思?应该是[true, true, true]? -
@AlexRudenko 不,这意味着:[假,真,假]
-
请使用
true和false而不是-1和1。使代码更容易理解。 (是的,我知道没有BooleanStream...至少使用0/1。)
标签: java functional-programming