I Have 2 ArrayList in my project. I want to get items which is not equal.
For Example:
LIST 1 - LIST 2
AB ------- AB
BA ------- BA
CC
I wanna get this CC. I'm doing like this:
ArrayList<String> alllist= new ArrayList<>(ArrayList<String> 1);
for (String i : ArrayList<String> 1) {
for (String j : ArrayList<String> 2) {
if (i.equals(j)) {
alllist.remove(i);
break;
}
}
}
This work if I haved 3 or 4 items in ArrayList but when I add 200 items this method doesn't work fine and getting wrong list.
Any idea? what can I do more?
Thanks a lot.
If I understand your question correctly, you are looking for a symmetric difference. You can use CollectionUtils.disjunction from Apache Commons Collections
Given:
List<String> list1 = Arrays.asList("AB", "BA", "DD");
List<String> list2 = Arrays.asList("AB", "BA", "CC");
Action:
System.out.println(CollectionUtils.disjunction(list1, list2));
Result:
[DD, CC]
If you need everything in list 1 but not list 2
1) Walk the first list and add each element to a HashSet.
2) use set.removeAll(list2) to remove everything in list 2.
The remainder is what's in list1 and not list2.
If you need to get everything in either list not in the other, you can repeat that in reverse. This should reverse the operation to O(n+m) where n is the length of list 1 and m is the length of list 2. Your pseudocode is O(n*m).
HashSet firstButNotSecond = new HashSet(list1);
firstButNotSecond.removeAll(list2);
HashSet secondButNotFirst = new HashSet(list2);
secondButNotFirst.removeAll(list1);
ArrayList<String> list2 = new ArrayList();
list2.add("AB");
list2.add("BA");
ArrayList<String> list1 = new ArrayList();
list1.add("AB");
list1.add("BA");
list1.add("C");
//remove all the element from the list1 which are also in list2
list1.removeAll(list2);
System.out.println("Result: " + list1); //only C will left behind
Related
list1 [1,2,3,4,5,6] --base list
list2 [1,2,4,3,6,5]
output: 4,6 are in incorrect order
I have to check the order should be as per list1. If not then i have to print all the elements which are not in correct order as per list1.
Stepping through the two lists and printing elements that are different is pretty simple, but it seems you only want to output differing elements once. For this you'd need to keep track of which you'd already seen, e.g. using a Set.
static void listCompare(List<Integer> list1, List<Integer> list2)
{
Set<Integer> seen = new HashSet<>();
int minLen = Math.min(list1.size(), list2.size());
for(int i=0; i<minLen; i++)
{
if(list1.get(i) != list2.get(i) && !seen.contains(list2.get(i)))
{
seen.add(list1.get(i));
System.out.format("%d (%d)%n", list2.get(i), list1.get(i));
}
}
}
Test:
List<Integer> list1 = Arrays.asList(1,2,3,4,5,6);
List<Integer> list2 = Arrays.asList(1,2,4,3,6,5);
listCompare(list1, list2);
Output:
4 (3)
6 (5)
You can compare value of list1 with list2 using list iterator and if compare result gives false then you can print value of list2.
It has been a long since something came to my mind while starting to code and using lists or array lists. When comparing values of one array to every other elements in another array, I used to do it in two for loops since it was the easiest way to do that.but recently I came to know that it increases much time complexity, I thought about another solution.can anyone help me in solving this case using any algorithm. I am using java.but solution in any language would be fine. just the algorithm to do that is needed. Thanks in advance.
This is what i am doing:
a1 = [1,2,3,4,5]
b1 = [9,5,4,3,8,3,7]
I want to check how much time an element in a1 occurs in b1
So what i am doing is:
count = 0;
for(int i = 0;i <a1.length;i++)
{
for(j=0;j<b1.length;j++)
{
if (a1[i] == b1[j])
{
count = count+1;
}
}
}
print("count is" count);
Theres no need of loop to obtain what you want
ArrayList<Integer> l1 = new ArrayList<Integer>();
l1.add(1);
l1.add(2);
l1.add(3);
l1.add(4);
l1.add(5);
ArrayList<Integer> l2 = new ArrayList<Integer>();
l2.add(9);
l2.add(5);
l2.add(4);
l2.add(3);
l2.add(8);
l2.add(3);
l2.add(7);
ArrayList<Integer> lFiltered = new ArrayList<Integer>(l2);
lFiltered.removeAll(l1);
int Times = l2.size() - lFiltered.size();
System.out.println("number of migrants : " + Times);
Suffice it to to generate from l2 a list without elements and l1 and to count elements which have been removed
Use hashing, e.g. using a Set or Map
If you want to compare the objects as a whole:
properly implement equals and hashcode for your class (if not implemented already)
put all the elements of list A into a Set, then see which elements from list B are in that Set
If you just want to compare objects by some attribute:
define a method that maps the objects to that attribute (or combination of attriutes, e.g. as a List)
create a Map<KeyAttributeType, List<YourClass>> and for each element from list A, add the element to that Map: map.get(getKey(x)).add(x)
for each element from list B, calculate the value of the key function and get the elements it "matches" from the map: matches = map.get(getKey(y))
Given your code, your case seems to be a bit different, though. You have lists or arrays of numbers, so no additional hashing is necessary, and you do not just want to see which items "match", but count all combinations of matching items. For this, you could create a Map<Integer, Long> to count how often each element of the first list appears, and then get the sum of those counts for the elements from the second list.
int[] a1 = {1,2,3,4,5};
int[] b1 = {9,5,4,3,8,3,7};
Map<Integer, Long> counts = IntStream.of(b1).boxed()
.collect(Collectors.groupingBy(x -> x, Collectors.counting()));
System.out.println(counts); // {3=2, 4=1, 5=1, 7=1, 8=1, 9=1}
long total = IntStream.of(a1).mapToLong(x -> counts.getOrDefault(x, 0L)).sum();
System.out.println(total); // 4
Of course, instead of using the Stream API you can just as well use regular loops.
Use ArrayLists.
To compare the content of both arrays:
ArrayList<String> listOne = new ArrayList<>(Arrays.asList(yourArray1);
ArrayList<String> listTwo = new ArrayList<>(Arrays.asList(yourArray);
listOne.retainAll(listTwo);
System.out.println(listOne)
To find missing elements:
listTwo.removeAll(listOne);
System.out.println(listTwo);
To enumerate the Common elements:
//Time complexity is O(n^2)
int count =0;
for (String element : listOne){
for (String element2: listTwo){
if (element.equalsIgnoreCase(elemnt2){
count += 1;
}
}
}
I am looking to prepend the elements of a java.util.ArrayList L1 to another java.util.ArrayList L2 and I cannot find an out of the box way to do it. I do not want to create a third ArrayList and hack around as L2 is the List being used in the view layer. Neither java.util.Collections nor org.apache.commons.collections.CollectionUtils has such a utility method (as far as I can see).
How can I efficiently prepend an ArrayList to another ArrayList, using existing API preferably ? For a java 7 environment.
P.S: addAll appends, I want to prepend.
Use List#addAll(int,Collection):
Inserts all of the elements in the specified collection into this list at the specified position (optional operation). Shifts the element currently at that position (if any) and any subsequent elements to the right (increases their indices). The new elements will appear in this list in the order that they are returned by the specified collection's iterator. The behavior of this operation is undefined if the specified collection is modified while the operation is in progress. (Note that this will occur if the specified collection is this list, and it's nonempty.)
If you use 0 as the index it will prepend the given Collection to the List. For example:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
list1.add("Item #1");
list1.add("Item #2");
list2.add("Item #3");
list2.add("Item #4");
System.out.println("List #1: " + list1);
System.out.println("List #2: " + list2);
list2.addAll(0, list1);
System.out.println("Combined List: " + list2);
}
}
Output:
List #1: [Item #1, Item #2]
List #2: [Item #3, Item #4]
Combined List: [Item #1, Item #2, Item #3, Item #4]
subList gives you a view into a list. If you make a view at the very start of the list, addAll will do the right thing.
ArrayList<String> list = new ArrayList<String>(Arrays.asList("extant1", "extant2"));
ArrayList<String> prefix = new ArrayList<String>(Arrays.asList("prefix1", "prefix2"));
list.subList(0, 0).addAll(prefix);
list
// => list ==> [prefix1, prefix2, extant1, extant2]
Simply You can do this way:
List<String> l1 = new ArrayList<>();
List<String> l2 = new ArrayList<>();
l1.add("a");
l1.add("b");
l2.add("c");
l2.add("d");
l1.addAll(l2);
System.out.println(l1); // if you want result in list 1
l2.clear();
l2.addAll(l1);
System.out.println(l2); // if you want result in list 2
I don't see any particular inbuilt function that can do this thing. Here is the trick I am following to solve this.
If L1 is {1,2} and L2 is {3,4} then
Reverse the list L1 (It will become {2,1} )
Iterate the list L2 from back and add the
elements to L1. (You can also reverse L2 and do addAll on L1. If you
are ok with modifying L2, do it) (L1 will become {2,1,4,3} )
Reverse the list L1 (L1 will become {3,4,1,2} )
Total Time Complexity : O(m+n) where m is size of L1 and n is size of L2
List<Integer> li1 = new ArrayList<>();
li1.add(1);
li1.add(2);
List<Integer> li2 = new ArrayList<>();
li2.add(3);
li2.add(4);
Collections.reverse(li1);
ListIterator<Integer> listIterator = li2.listIterator(li2.size());
while (listIterator.hasPrevious())
{
Integer previous = listIterator.previous();
li1.add(previous);
}
Collections.reverse(li1);
System.out.println(li1);
If you don't want to use Collections.addAll​(int index, Collection c)
public static void main(String[] args) {
List<String> orginalList = new ArrayList<>(Arrays.asList( "E","F","G","H"));
System.out.println(orginalList);
Collections.reverse(orginalList);
List<String> newList = new ArrayList<>(Arrays.asList( "A","B","C","D"));
System.out.println(newList);
Collections.reverse(newList);
orginalList.addAll(newList);
Collections.reverse(orginalList);
System.out.println(orginalList);
}
Checking docs.oracle showed me one function. ArrayList.add(int index, E element) This helps, because you can place the items of the ArrayList at the beginning of the array, for example:
ArrayList <Integer> L1 = {2, 3, 5, 7} /*Imaginary declaration*/, L2 = {500, 600};
for(int i=0; i<L1.size(); i--) L2.add(0, L1.get(i));
But this will leave L2 with {7, 5, 3, 2, 500, 600} because each element added at index [0] will push the next ones forward. Instead, do it the opposite way:
for(int i=L1.size()-1; i>=0; i++) L2.add(0, L1.get(i));
I have 2 lists,
listA = Amy, Bob, Dan
and
listB = Amy123, Bob23, Pam92, Dan45, Vince55
How do I create a list that contains the values in listB that begin with the values in listA, using regex?
The result list should look like this:
mergedList = Amy123, Bob23, Dan45
In case the matching criterion is that the elements should start with the same string:
List<String> listA = Arrays.asList("Amy", "Bob", "Dan");
List<String> listB = Arrays.asList("Amy123", "Bob23", "Pam92", "Dan45", "Vince55");
List<String> mergedList = listB.stream().filter(elementB -> listA.stream().anyMatch(elementA -> elementB.startsWith(elementA))).collect(Collectors.toList());
My Observation :
1) You have two lists : listA and listB
2) logic is to match items of listA with listB. If listA item is found(in part using regex or some other method OR as whole) in listB, then push listB item to mergelist, otherwise ignore listB item.
Heres what you can do :
1) I am using Java8 lambdas.
2) I havent used regex in this code. I guess you dont really need regex here. After all you basically are searching a string in another string as part or in whole. I have used contains() method.
public static void main(String[] args){
List<String> list1 = Arrays.asList("Amy","Bob","Dan");
List<String> list2 = Arrays.asList("Amy123","Bob23","Pam92","Dan45","Vince55");
List<String> mergedList = new ArrayList<>();
list1.forEach(item1 -> {
list2.forEach(item2 -> {
if(item2.contains(item1))
mergedList.add(item2);
});
});
mergedList.forEach(System.out::println);
}
3) The code outputs this :
Amy123
Bob23
Dan45
I have given the two arrays
array 1 : a, b, c, d
array 2 : a, b, c
I have used the
ArrayList<String> combine = new ArrayList<String> ()
and all the elements in array 1 and array 2
By sorting, I have found
a , a , b , b , c , c , d
Would you please tell me how to compare the elements in these two arrays and return the distinct items (d for example)?
Something like
ArrayList<String> charsA = new ArrayList<>();
charsA.addAll(Arrays.asList("a", "a", "b", "c", "d"));
ArrayList<String> charsB = new ArrayList<>();
charsB.addAll(Arrays.asList("a", "b", "c"));
charsA.removeAll(charsB);
System.out.println(charsA);
prints
[d]
Obviously use a different list if you don't want any of the two original to be affected.
The removeAll(Collection) method
Removes from this list all of its elements that are contained in the
specified collection.
If you want to do it with Arrays then you have to loop over both the arrays and compare values one by one. If you want to do it with ArraysLists then you can build your logic around contains() and remove() methods.
List<String> list1 = new ArrayList<String>();
list1.add("a");
list1.add("b");
list1.add("c");
list1.add("d");
List<String> list2 = new ArrayList<String>();
list2.add("a");
list2.add("b");
list2.add("c");
List<String> distinctList = new ArrayList<String>();
for (String string : list1) {
if (!list2.contains(string)) {
distinctList.add(string);
}
}