Reputation:
Let's suppose I have a List
List<String> allElements = new ArrayList<>(Lists.asList("A", "B", "C", "D", "F"));
And then another List
List<String> randomElements = new ArrayList<>(Lists.asList("B", "D", A", "Z"));
Now I want to check if allElements
contains 3 or more elements from randomElements
. If only 2 or less then I don't want it to fire up true. (The example above should return true)
How would I go about this?
I could use allElements.deleteAll(randomElements)
and get the length of allElements
, but that's not ideal since I want to work with the variable's values later (and this way I would delete them) and using deleteAll
each loop on temp variables isn't very elegant.
Is there a different way?
In a short way, I want to get the amount of elements that have the same value with different List no matter what index they're at.
edit: I used a solution from @Jesper Hustad
boolean listCheck(ArrayList allElements, ArrayList randomElements){
int count = 0;
for(Element a: allElements){
for(Element b : randomElements){
if(a==b){
count++;
}
}
}
return count==3;
}
I don't know if this is the most efficient solution (probably not), but it's the most clean for me.
Upvotes: 2
Views: 1842
Reputation: 4501
Best way to do this is use HashSet data structure from java.util package:
import java.util.*;
List<String> allElements = new ArrayList<>(Arrays.asList("A", "B", "C", "D", "F"));
List<String> randomElements = new ArrayList<>(Arrays.asList("B", "D", "A", "Z"));
Set<String> allElementsSet = new HashSet<>(allElements);
int count = 0;
Iterator<String> randomElementsIt = randomElements.iterator();
List<String> resultList = new ArrayList<>();
while (randomElementsIt.hasNext()) {
String nextRandom = randomElementsIt.next();
if (allElementsSet.contains(nextRandom)) {
count++;
}
if (count == 3) {
resultList.add(nextRandom);
count = 0;
}
}
// resultList - contains all elements
or you can use more functional way:
List<String> result = randomElements.stream()
.filter(allElementsSet::contains)
.map(randomElement -> new Pair<>(randomElement, 1))
.collect(Collectors.toMap(
pair -> pair.fst,
pair -> pair.snd,
Integer::sum)
)
.entrySet().stream()
.filter(pair -> pair.getValue() >= 3)
.map(Map.Entry::getKey).collect(Collectors.toList());
HashSet structure is useful for fast finding element is in some group. Method contains works for O(1). In this decision lists are not changes and you just create a new data structure from randomElements list.
Upvotes: 0
Reputation: 352
This should work, but im not sure it's the most efficient:
boolean listCheck(ArrayList allElements, ArrayList randomElements){
int count = 0;
for(Element a: allElements){
for(Element b : randomElements){
if(a==b){
count++;
}
}
}
return count==3;
}
Upvotes: 0
Reputation: 40098
You can use the stream
but i would suggest to use limit
for better performance. As suggested in comment by @Andy Turner you can use Set
for better improvement
return randomElements.stream()
.filter(i->list1.contains(i))
.limit(3)
.count() >= 3
Upvotes: 4
Reputation: 586
This sounds like a mathematical problem.
Basically you need to compare each element from list allElements with list randomElements. You can do that by implementing two for-loops like this
int countEqualMatches = 0;
for(String a : allElements){
for(String b : randomElements){
if(a.equals(b)){
countEqualMatches++;
}
}
}
System.out.println(countEqualMatches);
Also if allElements contains "A" two times and randomELements contains "A" two times you would get a count of 4 matches. Depends on the situation if you want this.
Also the first approach needs a lot of comparison tasks and is kinda cpu heavy if your lists get longer
If you can do something like an "alphbetical-ordering" of one or both lists you can implement a far more efficient method to compare the two lists. Normally you can just use java list.order(); function
if both lists are ordered you can start on the very lowest elements and compare these. if they are equal do ++, if not shift the smaller element away on one list and compare again. this way you get a 2N instead of a N^2 runtime in your compare function, however it might cost some to order the lists beforehand...
Pick whatever fits you better :)
Upvotes: 0