I have 2 array list that contain strings:
List1 = [no, yes, ok, not]
List2 = [no, but, vote, check]
Now, how do I compare List1 with List2 and remove the words in List1 if the same word are found in List2. The sorted word(without the same word) are stored in another arraylist.
Outcome should be like this:
List3 = [yes, ok, not]
If you want to store the result in a new list, you need to clone List1 first:
ArrayList list3 = (ArrayList) list1.clone();
or
ArrayList list3 = new ArrayList(list1);
Then use removeAll:
list3.removeAll(list2);
ArrayList provides method to remove all object present in another list.
Refer Removing elements present in collection
In your case list1.removeAll(list2) should solve your problem
You can create third list , add to it your two lists and find in it third list same words. When you find them , delete one.So you'll check your third list with equals().
I suppose you didn't know about the removeAll(Collection c) method present for ArrayLists or just want another way of doing it.
Since you mention that you need to remove the duplicated words from list1, initialize a HashSet and add all the values in list2 to the Set, like so,
Set<String> set = new HashSet<String>();
for(String s: list2)
set.add(s);
Now, do the same with a clone of list1, taking care to remove the strings from list1.
String[] list3 = new String[list1.size()];
list1.toArray(list3);
for(String s: list3)
if(!set.add(s))
list1.remove(s);
This is done in O(n) time, but takes some auxiliary storage. Please let me know if this solved your problem.
Related
I have 2 text files with data. I am reading these files with BufferReader and putting the data of one column per file in a List<String>.
I have duplicated data in each one, but I need to have unique data in the first List to confront with the duplicated data in the second List.
How can I get unique values from a List?
It can be done one one line by using an intermediate Set:
List<String> list = new ArrayList<>(new HashSet<>(list));
In java 8, use distinct() on a stream:
List<String> list = list.stream().distinct().collect(Collectors.toList());
Alternatively, don't use a List at all; just use a Set (like HashSet) from the start for the collection you only want to hold unique values.
Convert the ArrayList to a HashSet.
List<String> listWithDuplicates; // Your list containing duplicates
Set<String> setWithUniqueValues = new HashSet<>(listWithDuplicates);
If for some reason, you want to convert the set back to a list afterwards, you can, but most likely there will be no need.
List<String> listWithUniqueValues = new ArrayList<>(setWithUniqueValues);
In Java 8:
// List with duplicates
List<String> listAll = Arrays.asList("A", "A", "B", "C", "D", "D");
// filter the distinct
List<String> distinctList = listAll.stream()
.distinct()
.collect(Collectors.toList());
System.out.println(distinctList);// prints out: [A, B, C, D]
this will also work with objects, but you will probably have to adapt your equals method.
i just realize a solution may be it can be helpful for other persons.
first will be populated with duplicated values from BufferReader.
ArrayList<String> first = new ArrayList<String>();
To extract Unique values i just create a new ArrayList like down:
ArrayList<String> otherList = new ArrayList<>();
for(String s : first) {
if(!otherList.contains(s))
otherList.add(s);
}
A lot of post in internet are all speaking to assign my Arraylist to a List , Set , HashTable or TreeSet.
Can anyone explain the difference in theory and whitch one is the best tu use in practice ?
thnks for your time guys.
I have a ArrayList as below.
ArrayList<ArrayList<String>> a = new ArrayList<ArrayList<String>>();
Where ArrayList 'a' contains two ArrayList of string as below.
[a,b,c,d] & [1,2,3,4]
How to merge these two list into a single list as below.
[a,b,c,d,1,2,3,4]
Thanks In Advance.
You combine a foreach loop and the addAll method.
Example
ArrayList<String> combined = new ArrayList<String>();
for(ArrayList<String> list : a) {
combined.addAll(list);
}
How this works?
A for each loop will traverse through every member of a Collection. It has a temporary variable, in this case list that it assigns the current element too. All you're doing is adding every element inside each value for list, to one ArrayList named combined.
Just iterate through all the inner lists of a using foreach loop and addAll to result arraylist
ArrayList<String> merged = new ArrayList<String>();
for(ArrayList<String> list : a){
merged.addAll(list);
}
EDIT:
As #Lubo pointed out.
Note that this way you can end up with many arrays being created and thrown away internally in ArrayList. If you have large lists (number of contained elements), consider looking here: Union List
This should work
ArrayList<ArrayList<String>> a = new ArrayList<ArrayList<String>>();
List<String> result = new ArrayList<String>();
for (ArrayList<String> arrayList : a) {
result.addAll(arrayList);
}
Look into main loop and get each list in it and add to your result list.
We have some other ways too, If you can use Apache commons-collection
ListUtils.union(java.util.List list1, java.util.List list2)
Returns a new list containing the second list appended to the first list.
Use ArrayList.addAll(). Something like this should work (assuming lists contain String objects; you should change accordingly).
List<String> combined = new ArrayList<String>();
combined.addAll(firstArrayList);
If you need an Iterable, you can use Guava:
Iterables.concat(Iterable<? extends Iterable<? extends T>> inputs)
And if you really need a List, you can cast a resulting Iterable to a List using this:
Lists.newArrayList(Iterable<? extends E> elements)
or
Lists.newLinkedList(Iterable<? extends E> elements)
Java 8 streams provide another solution:
List<List<String>> list = Arrays.asList(
Arrays.asList("1", "2"),
Arrays.asList("3", "4"),
Arrays.asList("5", "6")
);
List<String> merged = list
.stream()
.reduce(new ArrayList<>(),(accumulator, sublist) -> {accumulator.addAll(sublist);return accumulator;});
System.out.println(merged);
It is similar to the accepted answer: you loop through your list (using Stream.reduce) to add all of your sublists elements to your merged list.
List<Integer> one = Arrays.asList(1, 2,3);
List<Integer> two = Arrays.asList(4, 5,6);
List<Integer> out = Stream.of(one, two)
.collect(ArrayList::new, (listStream, item) -> listStream.addAll(item), (item1, item2) -> {});
System.out.println(out);
Merging lists without loop with Guava
Using FluentIterable.transformAndConcat.
Applies function to each element of this fluent iterable and returns a fluent iterable with the concatenated combination of results. function returns an Iterable of results.
Usage
List<String> combined = FluentIterable.from(a)
.transformAndConcat(Functions.identity())
.toList();
This question already has answers here:
Remove duplicates from ArrayLists
(14 answers)
Closed 9 years ago.
In my program I have an array list containing product objects in it. I want to remove duplicated product objects from it. Is there any efficient way other than looping over each element and compare them.
just add all element into set. it wont allow duplicate values
List<Product> list=new ArrayList<>();
Set<Product> set=new HashSet<>();
set.addAll(list);
Just pass your list Collection to Hashset constructor and Get it back.
Then that one liner will be,
list = new ArrayList<E>(new HashSet<E>(list));
You can just put element into Set. Set keep unique values only.
List<String> list=new ArrayList<>();
Set<String> set=new HashSet<>();
set.addAll(list); // now you have unique value set
If you want to final result as unique value List just you need to get this Set as List
List<String> uniqueValList=new ArrayList<>(set);
You can use a Set but you will loose the original order of your list.
What you can do to keep the order is:
Set<E> copied = new HashSet<>();
List<E> res = new ArrayList<>();
for(E e : originalList) {
if(!copied.contains(e)) {
res.add(e);
}
copied.add(e);
}
Use Set instead of list it will remove duplicates
Try to use Set instead of List. Set wont allow duplicate values.
The advice above to use Set is good - but if you need to keep the order just use a LinkedHashSet http://docs.oracle.com/javase/7/docs/api/java/util/LinkedHashSet.html
List<String> list = ...
Set<String> set = new LinkedHashSet<>(list);
list.clear();
list.addAll(set);
That will preserve order and remove all duplicates.
The result will be case sensitive though in the case of strings.
Okey, I'm not a professional programmer so my question might sound silly.
I have this code:
ArrayList<Integer> list1 = new ArrayList<Integer>();
list1 = list2;
Please take note that list2 has three items inside [1, 2, 4]. So now, list1 has the same items inside.
But when I call remove(index) method. It removes that item from both ArrayLists.
This is my complete code:
ArrayList<Integer> list1 = new ArrayList<Integer>();
list1 = list2;
for (int i = 0; i < list1.size(); i++) {
if (list1.get(i) == practiceId) {
list1.remove(i);
}
}
The purpose I'm doing this is to solve a problem which has other solutions. I'm asking this question just because I'm curious and would like to know why this happens? And how would one remove an item without removing from both ArrayLists?
Also, I have some ideas why this is happening. When I tried debugging the code step-by-step, it shows that the both ArrayLists have the same id. So I thought this might be the cause of the problem. If this is true, then is there a way to make a new ArrayList and put all items inside other ArrayList in the new one without having to add all items one by one?
So when you set those two lists equal to each other I don't think you are doing what you think you're doing. That sounded funny. When you do it the way that you have above you are actually setting the memory address of list1 to the same as list2. So now that they both point to the same place in memory when you remove it will remove from both lists.
Make sense??
It is because ArrayList stores Objects and you are saying list1 = list2 which sets their reference the same, what you need to do is create another ArrayList called list2, so that their values but not their reference is the same, you can do this by.
list2.equals(list1);
when you are doing list1 = list2it is eventually making both object same., and while trying to delete items from one it is in terms deleting from both as both objects have same instance value.
if you want to copy items you can do as follows.
ArrayList list1 = new ArrayList();
for (int i = 0; i < list2.size(); i++) {
list1.add(list2.get(i));
}
the above code will copy list items from list2 to list1 and would be different objects now.
Now you can do operations on one list and it wont affect another list
Dont use list = list2 for copying content of arraylists. it just add a refrence to the original arraylist. For copying the content of arraylist use this:
list1.addAll(list2);
Pretty much all answers mentioned are helpful.
But as I mentioned before, I don't want to add elements one by one. There was an answer which was:
ArrayList<Integer> list1 = new ArrayList<Integer>(list2);
Which was unfortunately deleted by poster. Anyways, this is exactly what I'm looking for. Clean, one line and no need for extra methods or loops or anything.
Thanks for your answers :)
I hope this help will you
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Integer> list2 = new ArrayList<Integer>();//added 1, 2, 4
list1 = (ArrayList<Integer>) list2.clone();
When you do list2 = list1, the same reference is copied to the the second list, so whatever changes you do in one list, same will happen in other. To successfully do this, you should use this :-
list2.addAll(1);
Now, if you will remove from list2, only items will be removed from list2 and not list1
I've two ArrayList both containing Integer values. My objective is to get identical/common/duplicate values comparing these 2 list. In other words (in SQL parlance), I need the INTERSECT result of two lists, that is, values that appear in both list.
Example:
ArrayList<Integer> list1 = new ArrayList<Integer>();
list1.add(100);
list1.add(200);
list1.add(300);
list1.add(400);
list1.add(500);
ArrayList<Integer> list2 = new ArrayList<Integer>();
list2.add(300);
list2.add(600);
One kind of implementation/solution I could think along is looping one of the list something like:
ArrayList<Integer> intersectList = new ArrayList<Integer>();
for (Integer intValue : list1)
{
if(list2.contains(intValue))
intersectList.add(intValue);
}
In this case, intersectList would contain only 1 Integer item being added, that is 300, which appears in both list.
My question is, are there any better/fastest/efficient way of implementing this logic? Any options available in Apache Commons library?. Any other ideas/suggestions/comments are appreciated.
NOTE: For illustration purpose, I've just shown here 5 items and 2 items being added into the list. In my real-time implementation, there will be more than 1000 elements in each list. Therefore, performance is also a key factor to be considered.
If you're okay with overwriting result for list1:
list1.retainAll(list2);
otherwise clone/copy list1 first.
Not sure on performance though.
list1.retainAll(list2)//for intersection
Use ListUtils from org.apache.commons.collections if you do not want to modify existing list.
ListUtils.intersection(list1, list2)