I have an array list
ArrayList<String> list=new ArrayList<String>();
list.add("Apple");
list.add("Ball");
list.add("Ball");
list.add("Cat");
list.add("Cat");
list.add("dog");
and I want to transfer duplicate strings to other ArrayList.
I mean 2nd array list should only contain Ball and Cat not Apple and dog.
Any kind of help is appreciated.
You can do this:
List<String> duplicates = new ArrayList<String>();
for(String str: list) {
if(Collections.frequency(list, str) > 1) {
duplicates.add(str);
}
}
duplicates will contain your duplicates
Try this:
// Custom list to ensure that one duplicate gets added to a list at most as
// opposed to n-1 instances (only two instances of a value in this list would
// be deceiving).
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Ball");
list.add("Ball");
list.add("Ball");
list.add("Ball");
list.add("Cat");
list.add("Cat");
list.add("Cat");
list.add("dog");
list.add("dog");
Set<String> set = new HashSet<>();
Set<String> setOfDuplicates = new HashSet<>();
for (String s : list) {
if (!set.add(s)) { // Remember that sets do not accept duplicates
setOfDuplicates.add(s);
}
}
List<String> listOfDuplicates = new ArrayList<>(setOfDuplicates);
You can use a Set as a way to help determine the duplicated elements then simply return an ArrayList of those elements.
public static ArrayList<String> retainDuplicates(ArrayList<String> inputList){
Set<String> tempSet = new HashSet<>();
ArrayList<String> duplicateList = new ArrayList<>();
for (String elem : inputList) {
if(!tempSet.add(elem)) duplicateList.add(elem);
}
return duplicateList.stream().distinct().collect(Collectors.toCollection(ArrayList::new));
}
call the method like so:
ArrayList<String> resultList = retainDuplicates(list);
note that I've used distinct() to remove any elements that occur more than once within the duplicateList. However, if you want to keep the duplicates regardless of theirs occurrences within the duplicateList then just perform return duplicateList; rather than return duplicateList.stream().distinct().collect(Collectors.toCollection(ArrayList::new));.
since you said your duplicates will all be next to each other, you can itterate through the list in pairs, and if the pair's elements match, there is a duplicate
here would be the general pseudo code for it
int first = 0
int second = 1
for (arraySize)
if (array[first] == array[second])
//there is a match here
newArray.add(array[first])
first += 1
second += 1
Note that this does not check the bounds of the array, which should be easy to implement yourself
now as for the second list not having duplicate items, you can simply store a variable with the last transfered item, and if the new found duplicate is the same, dont transfer it again
ArrayList<String> list=new ArrayList<String>();
list.add("Apple");
list.add("Ball");
list.add("Ball");
list.add("Cat");
list.add("Cat");
list.add("dog");
List<String> duplicateList= new ArrayList<String>();
for(String str: list) {
if(Collections.frequency(list, str) > 1) {
duplicateList.add(str);
}
}
System.out.println(duplicateList.toString());
//Here you will get duplicate String from the original list.
Related
I have an array and i want to compare the first element of this array with every element of another array in an Arraylist?
The purpose of doing this is to check whether or not the first element of the array exist in the another array of an Arraylist.
is this possible?
if yes, how?
List<List<String>> arrayst = new ArrayList<List<String>>();
List<List<String>> arrayqu = new ArrayList<List<String>>();
List<List<String>> arrayya = new ArrayList<List<String>>();
List<String> items = Arrays.asList(line.split(":",-1));
// i want to compare 1st element of items with 3 of the list above.
Create a different class and try something like this -
public class StackOverflow {
public void compare(List<String> items, List<List<String>> list){
String itemToBeCompared=items.get(0);
for(List<String> l:list){
if(l.contains(itemToBeCompared)){
System.out.println("Its Present");
}
else{
System.out.println("Not Present");
}
}
}
}
Then in the main method do something like this -
List<List<String>> arrayst = new ArrayList<List<String>>();
List<List<String>> arrayqu = new ArrayList<List<String>>();
List<List<String>> arrayya = new ArrayList<List<String>>();
List<String> items = Arrays.asList(line.split(":",-1));
StackOverflow st=new StackOverflow();
st.compare(items,arrayst);
st.compare(items,arrayqu);
st.compare(items,arrayya);
Hope this helps! Please let me know if this works for you.
I have a 2d ArrayList which stores objects, i want to check if a certain object exists in any of of the rows, and if not add a new row, and search that object in future checks. eg.
ArrayList<List<Object>> list = new ArrayList<>();
for(List<Object> o : list) {
if(!o.contains(object){
ArrayList<Object> newList = new ArrayList<>();
newList.add(object);
list.add(newList);
}
}
This gives me a 'ConcurrentModificationException' but I can't find another way to do it.
Thanks in advance.
list.add(newList); this line should be outside your for loop. You are trying to modify your list while iterating on it. Just keep adding elements to newList in the for loop. Add the line list.add(newList); after the for loop.
You cannot change a List while you are iterating over its items.
What you can do is:
ArrayList<List<Object>> list = new ArrayList<>(); // in practice this would not be an empty list, but it would, as in your example, contain all items
ArrayList<List<Object>> newRows = new ArrayList<>();
for(List<Object> o : list) {
if(!o.contains(object){
ArrayList<Object> newList = new ArrayList<>();
newList.add(object);
newRows.add(newList);
}
}
list.addAll(newRows);
You have to replace:
for(List o : list) {
with:
for(int i = 0; i < list.size(); i++) {
List o = list.get(i);
Just be careful when you do this to handle how you modify the list. In this case there should be no problem.
I have List of ArrayList Elements, see below.
List<List<String>> x = new ArrayList<List<String>>();
it contains some array list elements.
eg.
x.get(0)->[1,2,3,4],
x.get(1)->([5,6,7,8],
x.get(2)->[9,10,11,12],
x.get(3)->[13,14,15,16]
i want to access element 3 from x.get(0) or element 7 from x.get(1) how to call that??
Each element of your list is a list and has the same interface that provides List<T> methods, e.g.
T get(int index)
boolean isEmpty()
void add(T element)
etc.
You can access element from the inner list by index
List<List<String>> x = new ArrayList<List<String>>();
// ... some data initialised
String element_0_3 = x.get(0).get(3);
Be aware that each List<String> element needs to have been created before accessing it. For instance, in order to add a new String at the [0,0] coordinates:
List<List<String>> x = new ArrayList<List<String>>();
List<String> x0 = new ArrayList<>();
x0.add("foo"); // add "foo" as the first string element
x.add(x0); // add x0 as the first List<String> element
You can also read values with an enhanced for loop, without using the indexes:
List<List<String>> x = new ArrayList<List<String>>();
//...
for (List<String> ls : x) { // iteration on the x list
for (String s : ls) { // iteration on each intern list
System.out.println(s);
}
You can follow like...
List<List<String>> x = new ArrayList<List<String>>();
List<String> subX = x.get(7);
if(null != subX && subX.size() != 0) {
String element = subX.get(0);
}
//To directly access any list member using for loop instead of foreach loop
List<List<Integer>> list = new ArrayList<List<Integer>>();
for(int i=0;i<list.size();i++){
for(int j=0;j<list.get(i).size();j++){
do_something_on(list.get(i).get(j);
}
}
I have a list of words which contains multiple duplicate words. I want to extract the words that are duplicated and store them in another list (maintaining the integrity of the original list).
I tried iterating through the list like you see below, but this fails logically because every 'dupe' will at some point be equal to primary. I really want to iterate through the list and for every String in the list check all the OTHER strings in the list for duplicates.
Is there a method in the List interface that allows this type of comparison?
For reference list 1 is a list of Strings.
for(String primary: list1){
for(String dupe: list1){
if(primary.equals(dupe)){
System.out.print(primary + " " + dupe);
ds3.add(primary);
}
}
}
EDIT:
I should note, that I'm aware that a Set doesn't allow for duplicates, but what I'm trying to do is OBTAIN the duplicates. I want to find them, and take them out and use them later. I'm not trying to eradicate them.
The easiest way to remove the duplicates is to add all elements into a Set:
Set<String> nodups = new LinkedHashSet<String>(list1);
List<String> ds3 = new ArrayList<String>(nodups);
In the above code, ds3 will be duplicate-free. Now, if you're interested in finding which elements are duplicate in O(n):
Map<String, Integer> counter = new LinkedHashMap<String, Integer>();
for (String s : list1) {
if (counter.containsKey(s))
counter.put(s, counter.get(s) + 1);
else
counter.put(s, 1);
}
With the above, it's easy to find the duplicated elements:
List<String> ds3 = new ArrayList<String>();
for (Map.Entry<String, Integer> entry : counter.entrySet())
if (entry.getValue() > 1)
ds3.add(entry.getKey());
Yet another way, also O(n): use a Set to keep track of the duplicated elements:
Set<String> seen = new HashSet<String>();
List<String> ds3 = new ArrayList<String>();
for (String s : list1) {
if (seen.contains(s))
ds3.add(s);
else
seen.add(s);
}
Consider using a Set. "A collection that contains no duplicate elements."
The intent is to extract the duplicates not lose them entirely
List<String> list =
Set<String> set = new LinkedHashSet<>(); // to keep he order
List<String> dups = new ArrayList<String>(); // could be duplicate duplicates
for(String s: list)
if (!set.add(s)) dups.add(s);
To obtain only the duplicates (as opposed to eliminating duplicates from the list), you can use a set as a temporary lookup table of what previous string has been visited:
Set<String> tmp = new HashSet<String>();
for(String primary: list1){
if(tmp.contains(primary)) {
// primary is a duplicate
}
tmp.add(primary);
}
I have two ArrayLists as shown - pinklist and normallist. I am comparing both of them and finding the unique and duplicate values from both as shown below in code:
List<String> pinklist = t2.getList();
List<String> normallist = t.getList();
ArrayList<String> duplicatevalues = new ArrayList<String>();
ArrayList<String> uniquevalues = new ArrayList<String>();
for (String finalval : pinklist) {
if (pinklist.contains(normallist)) {
duplicatevalues.add(finalval);
} else if (!normallist.contains(pinklist)) {
uniquevalues.add(finalval);
}
}
I am getting the duplicateValues properly, but I am not getting the unique values.
this should do:
List<String> pinklist = t2.getList();
List<String> normallist = t.getList();
ArrayList<String> duplicates = new ArrayList<String>(normallist);
duplicates.retainAll(pinklist);
ArrayList<String> uniques = new ArrayList<String>(normallist);
uniques.removeAll(pinklist);
Explaination:
Every List can take another list as a constructor parameter, and copy it's values.
retainAll(list2) will remove all entries, that does not exist in list2.
removeAll(list2) will remove all entries, that does exist in list2.
We don't want to remove/retain on the original lists, because this will modify it, so we copy them, in the constructor.
You're ignoring finalval in your conditions, instead asking whether one list contains the other list.
You could do it like this:
// Variable names edited for readability
for (String item : pinkList) {
if (normalList.contains(item)) {
duplicateList.add(item);
} else {
uniqueList.add(item);
}
}
I wouldn't really call these "unique" or "duplicate" items though - those are usually about items within one collection. This is just testing whether each item from one list is in another. It's more like "existing" and "new" in this case, I'd say.
Note that as you're treating these in a set-based way, I'd suggest using a set implementation such as HashSet<E> instead of lists. The Sets class in Guava provides useful methods for working with sets.
Try ListUtils https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/ListUtils.html
To get duplicate values use ListUtils.intersection(list1, list2)
To get unique values you could use ListUtils.sum(list1, list2) and then subtract the duplicates list
Do it this way -
for (String finalval : pinklist)
{
if(normallist.contains(finalval))
{
// finalval is both in pinklist and in
// normallist. Add it as a duplicate.
duplicatevalues.add(finalval); // this will get you the duplicate values
}
else {
// finalval is in pinklist but not in
// normallist. Add it as unique.
uniquevalues.add(finalval); // this will get you the values which are in
// pinklist but not in normallist
}
}
// This will give you the values which are
// in normallist but not in pinklist.
for(String value : normallist) {
if(!pinklist.contains(value)) {
uniquevalues.add(value);
}
}
Using Java8 Stream API we can filter lists and get expected results.
List<String> listOne = // Your list1
List<String> listTwo = // Your list2
List<String> uniqueElementsFromBothList = new ArrayList<>();
List<String> commonElementsFromBothList = new ArrayList<>();
// Duplicate/Common elements from both lists
commonElementsFromBothList.addAll(
listOne.stream()
.filter(str -> listTwo.contains(str))
.collect(Collectors.toList()));
// Unique element from listOne
uniqueElementsFromBothList.addAll(
listOne.stream()
.filter(str -> !listTwo.contains(str))
.collect(Collectors.toList()));
// Unique element from listOne and listTwo
// Here adding unique elements of listTwo in existing unique elements list (i.e. unique from listOne)
uniqueElementsFromBothList.addAll(
listTwo.stream()
.filter(str -> !listOne.contains(str))
.collect(Collectors.toList()));
Here's my solution to the problem.
We can create a set containing elements from both the lists.
For the unique elements, using the Stream API, we can filter out the elements based on the predicates returning XOR of contains method. it will return true only for true ^ false OR false ^ true, ensuring only one of them contains it.
For the distinct elements, simply change the XOR to &&, and it'll check if both lists have the objects or not.
Code:
private static void uniqueAndDuplicateElements(List<String> a, List<String> b) {
Set<String> containsAll = new HashSet<String>();
containsAll.addAll(a);
containsAll.addAll(b);
List<String> uniquevalues = containsAll.stream()
.filter(str -> a.contains(str) ^ b.contains(str))
.collect(Collectors.toList());
List<String> duplicatevalues = containsAll.stream()
.filter(str -> a.contains(str) && b.contains(str))
.collect(Collectors.toList());
System.out.println("Unique elements from both lists: " + uniquevalues);
System.out.println("Elements present in both lists: " + duplicatevalues);
}
Why are you passing entire list to the contains method? You should pass finalval rather.