I'm trying to create a function that gives a list of arrays and two arrays of integers as input:
public boolean[] checkMatching(ArrayList<String[]> items, Integer[] arr1, Integer[] arr2){...}
checks if there are at least two items that have the same values for the indices of arr1, but different values for the indices of arr2. For example:
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)
In the previous example the function should return:
[-1, 1, -1]
since item1, item2, and item5 share the same values for the indices of arr1, while they have different values for indices 0,4, and equal values for index 3.
Notice that, the method returns 3 integers since in arr2 there are 3 indices. Thus, each boolean refers to an index in arr2.
This could be a solution which exploits functional programming:
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;
}
}
But it is not very efficient, especially when there is a large amount of items. Is there anyone who can help me? I am trying to develop a very performing solution and I don't know if there are faster solutions than functional programming.
question from:
https://stackoverflow.com/questions/65881032/find-values-in-arraylist-with-specific-conditions