I have two lists, in one list values are 1,2,3
another list 2,3
I want to remove the values which are not matched in both lists.
2 and 3 are matched in both lists then 1 is not mached in both lists so I want to remove that value.
List original = [1,2,3];
List dummy = [2,3];
If it's possible to use sets instead, then you can just get the intersection between the sets (info):
Set<String> s1;
Set<String> s2;
s1.retainAll(s2); // s1 now contains only elements in both sets
Of course with sets you can't have duplicates and you'll lose ordering.
You don't need to use a Set to achieve your requirement.
Use retainAll() defined in Collection that any List implementation implements such as :
List<Integer> original = new ArrayList<>(Arrays.asList(1,2,3));
List<Integer> dummy = Arrays.asList(2,3);
original.retainAll(dummy);
System.out.println(original);
Output :
[2, 3]
If you are using Java 8+ you can use :
original.removeIf(a -> !dummy.contains(a));
Here is an example with Java 10
var original = new ArrayList<>(List.of(1, 2, 3, 4));
var dummy = new ArrayList<>(List.of(2, 4, 3));
original.removeIf(a -> !dummy.contains(a));
System.out.println(original);
->[2, 3, 4]
Related
I have two lists I want to compare each element of list 1 to list 2 and get result in list 3 e.g
List1 = {99,22,33}
list2 = {11,24,33}
Result:
list3 = {1,-1,0}
How I can do this preferably using stream?
Try it like this:
This replaces the stream of ints used to index each list, with the result of the comparison. Then collect those into a list.
Note: I added a safeguard to account for different size lists. It will use the smaller of the two to prevent an exception being thrown. But trailing elements of the longer list will be ignored.
List<Integer> list1 = List.of(99, 22, 33);
List<Integer> list2 = List.of(11, 24, 33);
// safeguard against different sized lists.
int minLen = Math.min(list1.size(), list2.size());
List<Integer> result = IntStream.range(0, minLen)
.map(i -> list1.get(i).compareTo(list2.get(i)))
.boxed().collect(Collectors.toList());
System.out.println(result);
Prints
[1, -1, 0]
I have two lists.
List<Integer> list1 = new ArrayList<>(Arrays.asList(1, 2, 2));
List<Integer> list2 = new ArrayList<>(Arrays.asList(2, 3, 4));
I want to remove the elements contained in list2 from list1, precisely as many times as they are contained in list2. In the example above: when we remove elements in list 1 which exist in list 2, we should get as result [1, 2] (only one occurrence of 2 should be removed from list1 because list2 contains only one instance of 2).
I tried with list1.removeAll(list2); but I got as result list containing only [1].
What is the best way to achieve this? Iterate through both lists simultaneous seems a bit ugly for me.
If I understand correctly, you only want to remove a single 2 element from list1 rather than all of them. You can iterate over list2 and attempt to remove each element from list1. Keep in mind that there are more efficient methods than this if list2 cannot contain duplicates.
var list1 = new ArrayList<>(List.of(1, 2, 2));
var list2 = List.of(2, 3, 4);
list2.forEach(list1::remove);
list1 now contains the following:
[1, 2]
See starman1979's answer for the same solution, but using a lambda rather than a method reference.
How about:
list2.forEach(i -> {
list1.remove(i); //removes only first occurrence - if found
});
list1 now contains
[1, 2]
Given
List<Integer> a = new ArrayList<>(Arrays.asList(1, 2, 2));
List<Integer> b = Arrays.asList(2, 3, 4);
Use one of the following variants to get the desired result:
1. Plain java
b.forEach((i)->a.remove(i));
a now contains
[1, 2]
Give credit at original post: add +1:
2. Apache Commons
In apache commons there is a subtract method
Collection<Integer> result = CollectionUtils.subtract(a, b);
result now contains
[1, 2]
Here is how they implemented it
3. Guava
Since guava doesn't offer a subtract method you may find this advice from the google implementors helpful
"create an ArrayList containing a and then call remove on it for each element in b."
Which basically renders to what was already mentioned under 1.
I need to provide a Java solution that given two list, a & b, that returns a value that is present in one list but not in another.
e.g.
lists a = [26, 13, 88, 9]
lists b = [26, 1, 8, 12]
for those kind of operation it would be better to use collections,
the method removeAll() will filter the data containers, from the doc:
Removes from this list all of its elements that are contained in the
specified collection (optional operation).
List<Integer> myVarListA = Arrays.asList(26, 13, 88, 9);
List<Integer> myVarListB = Arrays.asList(26, 1, 8, 12);
List<Integer> myVarListAcomplementB = new ArrayList<>(myVarListA);
List<Integer> myVarListBcomplementA = new ArrayList<>(myVarListB);
myVarListAcomplementB.removeAll(myVarListB);
myVarListBcomplementA.removeAll(myVarListA);
System.out.println("elements in A but no in B: " + myVarListAcomplementB);
System.out.println("elements in B but no in A: " + myVarListBcomplementA);
myVarListBcomplementA.addAll(myVarListAcomplementB);
System.out.println("both together: " + myVarListBcomplementA);
Simple solution is to calculate the intersection and remove that from the desired list. If you only want what is missing, you can optimize this a little by going a solution like ΦXocę 웃 Пepeúpa ツ.
The great thing about this solution is that you can easily expand this to use 3+ sets/lists. Instead of A-B = diff or A-I(A,B)=diff, you can also do A-I(A,I(B,C)) to find what A is missing from the common set between A, B and C.
public static <T> HashSet<T> intersection(Collection<T> a, Collection<T> b) {
HashSet<T> aMinusB = new HashSet<>(a);
aMinusB.removeAll(b);
HashSet<T> common = new HashSet<>(a);
common.removeAll(aMinusB);
return common;
}
Let's call the intersection set Collection I = intersection(a,b);.
Now if you want to find what is missing from list A that was in B:
new LinkedList(A).removeAll(I);//ordered and possibly containing duplicates
OR
new ArrayList(A).removeAll(I);//ordered and possibly containing duplicates. Faster copy time, but slower to remove elements. Experiment with this and LinkedList for speed.
OR
new LinkedHashSet<T>(a).removeAll(I);//ordered and unique
OR
new HashSet<T>(a).removeAll(I);//unique and no order
Also, this question is effectively duplicate of How to do union, intersect, difference and reverse data in java
You may try this:
a.removeAll(b);
Simply parse the second list and add unique elements to the first, delete others.
for (Integer elem : secondList)
if (firstList.contains(elem))
firstList.remove(elem);
else
firstList.add(elem);
In firstList you will have the values present only in one of the lists.
i got two Lists with integer IDs an old list and a new list.
Now i want to do three steps:
1. Check which IDs from (old)List1 are also found in (new)List2
2. Delete all elements from List1 that are not found in List2 after step 1
3. Add all missing IDs from List 2 to List 1
I was thinking of adding two boolean arrays and set a flag when an element was found, later i could delete the IDs elements from List1 and add the unchecked IDs from List2 in List1.
Maybe there are better ways?
Try it this way:
List<Integer> list1 = new ArrayList<>(Arrays.asList(1, 2, 3, 4));
List<Integer> list2 = new ArrayList<>(Arrays.asList(2, 3, 5, 6));
list1.retainAll(list2);
list2.removeAll(list1);
list1.addAll(list2);
System.out.println(list1);
OUTPUT:
[2, 3, 5, 6]
put all content in a lookup table, for instance use a HashSet.
i have two arraylist one have employee entity list other also have same entity list.
one Arraylist have all employees and other one have selected employees.
now i want to arrange employee in list in first Arraylist as on selected employees first arrive which is in second arraylist.
for Ex::
list1 [{1,test1}{2,test2},{3,test3},{4,test4}]
list2[{2,test2}{4,test4}]
what i want is
list1[{2,test2}{4,test4}{1,test1}{3,test3}]
How can i do this same by using single method or minimal line code ..
From what you have said it seems like you just need to take the members of list1 that are not in list2 and append them to list2 in the order they appear in list1.
Something like:
for ( Employee e : list1 ) {
if ( !list2.contains(e) ) {
list2.append(e);
}
}
Why not use Collections.sort(list1, yourComparator) where yourComparator sorts the entries in list1 as you need?
You could use Apache CollectionUtils like this:
CollectionUtils.addAll(list2, CollectionUtils.subtract(list1, list2));
You don't even need a loop or a comparator. Just use the Collections API!
Firstly, you want a LinkedHashSet - preserves uniqueness and order
Use the API to add list2, then list2, then populate a list with the set:
Here's an example using Integers:
// Set up your data
List<Integer> l1 = new ArrayList<Integer>(Arrays.asList(1, 2, 3, 4, 5));
List<Integer> l2 = new ArrayList<Integer>(Arrays.asList(2, 5));
// Here's the 3 lines that do the work
Set<Integer> set = new LinkedHashSet<Integer>(l2);
set.addAll(l1);
List<Integer> l3 = new ArrayList<Integer>(set);
// All done
System.out.println(l3); // "[2, 5, 1, 3, 4]"