I would like to get unique values from two Collection objects. How would I do that?
Example: Let us take two ArrayLists:
List bag1 = new ArrayList();
List bag2 = new ArrayList();
bag1.add("1");
bag1.add("2");
bag1.add("3");
bag1.add("7");
bag1.add("8");
bag1.add("9");
bag2.add("4");
bag2.add("5");
bag2.add("6");
bag2.add("7");
bag2.add("8");
bag2.add("9");
I need to get a result like --> 1,2,3 from bag1 and 4,5,6 from bag2
Could you please help me out?
Two things:
Use org.apache.commons.collections.CollectionUtils.disjunction(Collection a, Collection b);
Bag isn't the best variable name for a list. :)
You should take a look at Sets instead. The Java Collection has a few classes which deal with this. The idea is you could just the the set difference between the two collections, and you'll get your answer.
Use a 'set' to store your data. That way your collection will have unique elements as and when you add elements to the set.
See the javadoc over here: http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Set.html
have you tried...
bag1.removeAll(bag2);
If you want to keep bag1 and bag2 intact you can use a Set variable and pass all values of bag1 into the Set and then check for contains() like
Set set = new HashSet();
set.addAll(bag2);
for(Object o: bag1){
if(!set.contains(o)){
// Do whatever you want with bag1 elements
}
}
set.clear();
set.addAll(bag1);
for(Object o: bag2){
if(!set.contains(o)){
// Do whatever you want with bag2 elements
}
}
Use the removeAll method define in the Set interface.
Set intersect = new TreeSet(bag1);
intersect.removeAll(bag2);
List unique1 = Arrays.asList(intersect);
intersect = new TreeSet(bag2);
intersect.removeAll(bag1);
List unique2 = Arrays.asList(intersect);
Related
I'm trying to understand a very basic concept and I'm not sure why it doesn't work.
I have two lists of type, and I want to combine them into one Set with distinct values (as it should be by the definition of Set). However, when I print the set values I get duplicates.
List<SID> list1 = (.....)
List<SID> list2 = (.....)
Set<SID> combined = new HashSet<>();
combined.addAll(list1);
combined.addAll(list2);
I also tried with distinct()
Set<SID> combinedSet = Stream.concat(list1.stream(), list2.stream()).distinct().collect(Collectors.toSet());
List<SID> combinedList = Stream.concat(list1.stream(), list2.stream()).distinct().collect(Collectors.toList());
Any idea why?
SID class overrides the hashCode and the equals method...any other way to achieve it?
I have an ArrayList (~900 entries) containing arrays of user information:
[swaschit, Sophia Waschitz, Dormant, Inactive, 1/1/2018]
[kolanday, Kyle Olanday, Dormant, Inactive, 1/1/2018]
[npowers, Neil Powers, Assigned, Active, 2/11/2018]
I want to generate an array from this list containing only the first elements of each object:
[swaschit, kolanday, npowers, ...]
What is the most efficient way of doing this?
One way is to use a Stream and map each of the inner arrays to its first element:
List<String> firstElements = yourList.stream()
.map(x -> x[0].toString()) // you might need toString() here if your array is an Object[]
.collect(Collectors.toList());
If you would like an array of strings instead:
String[] firstElements = yourList.stream()
.map(x -> x[0].toString()) // you might need toString() here if your array is an Object[]
.toArray(String[]::new);
I also suggest you to not use nested arrays like this. You should create a class with the properties you want to store and create a List of your class.
As I suppose the first entry is unique (as it seems to be a username), I would suggest using a Map. That way, you could simply list the keys.
HashMap<String,ArrayList<String>> hashmap=new HashMap<>();
Alternatively, you could simply create a class containing that information, to avoid needing the use of an ArrayList, but I don't know if this is an option.
As pointed out using an appropriately designed Object rather than an array of such heterogeneous data (guessing they are Strings in reality).
If you insist on keeping it the way you have though, you just need to allocate a new array with the size of the original ArrayList and iterate through, fetching the desired column. Assuming ArrayList<String[]> list
int size = list.size();
String[] firstColumn = new String[size];
for (int i = 0; i < list.size(); i++) {
firstColumn[i] = list.get(i)[0];
}
I suppose that you can do
list.stream().map(array -> array[0].toString()).toArray()
I have three ArrayLists:
One is used for storing user input in the order they were entered, located in the main class.
Second one is exactly the same as the first one, but it is passed into a method called remTrip to be copied and will return the result.
Third one is list1 in the code below, which is the one being processed.
public static ArrayList<String> remTrip( ArrayList<String> a){
//code here
ArrayList<String> list1 = a;
Collections.sort(list1);
//code to remove triplicates from the list and returns the result
}
I wanted to keep the first ArrayList<String> in the same order it was (i.e. {"dog", "cat" , "tiger", "cat", "cat"} ), but apparently the Collections.sort() sorts all of the ArrayLists.
How do I sort only one of the list and not the others?
The problem is not how Collections.sort() works. The problem is that instead of creating a copy of your list, you set the new list equal to your list. This means that they both point to the same object, sorting one will sort the other because they are the same thing. To solve this set list1 to a copy of a instead of setting them equal.
You should be able to do
ArrayList<String> list1 = new ArrayList<String>(a);
Three arralists you're talking about are not 3 different arraylists. They're just three different references to the same arraylist.
What you're doing essentially is -
List list01 = new ArrayList();
List list02 = list01;
List list03 = list01;
What you want is -
List list01 = new ArrayList();
List list02 = new ArrayList(list01);
List list03 = new ArrayList(list01);
But you should remember, this way will give you a copy of your List, not all it's elements. So, if you change one of the elements in your copied List, it will be changed in your original List too.
How to solve it - Hint copy constructor.
I just found a code like this
ArrayList contacts = new ArrayList();
public void addContacts(Contact contact){
if(!contacts.contains(contact)){
contacts.add(contact);
}
}
I just wonder if I can omit the following line, !contacts.contain(contact) thus I can write like this
ArrayList contacts = new ArrayList();
public void addContacts(Contact contact){
contacts.add(contact); // adding the new contact directly without checking first
}
Why do I need to include the first line?
ArrayList allows duplicates, if you remove first line condition if(!contacts.contains(contact)), It will allow the duplicate elements in the contacts list
You could use Set interface to avoid implementation of duplicate entries. List interface doesn't provide any implementation to avoid duplicates. ArrayList allows duplicates.
List numList = new ArrayList();
numList.add(10);numList.add(20);numList.add(10);numList.add(20);
System.out.println("\nList elements before duplicates removal: " + numList);
Set mySet = new HashSet();
mySet.addAll(numList);
System.out.println("Set elements: " + mySet);
This will show result as :
List elements before duplicate removal: 10, 20, 10, 20
Set Elements: 20 , 10
In case, you want to preserve the order also, then you could use TreeSet implementation of Set interface.
Simple Solution:
Simple solution is change your implementation to Set interface to get more accurate results.
Array List allow us the duplicacy.And thsi is check to prevent the duplicate entries inside that arraylist.
IF you will remove that check then the list will hold the duplicate entries you tried to add.
Its would be better to prefer the set to avoid the duplicacy.
I want to know if there is a function in Java retrieve one string from array of strings if the other strings are the same i.e. if I have in my array :
yes,yes,yes,yes,no,no,no,no .. I want to get only one yes and one no and display them!
and not by using for loop and comparing ! , just I want to know if this function exists in Java .
Insert all those into a Set.Then u will get like that
String[] array = {"yes","yes","yes","yes","no","no","no","no"};
Set<String> mySet = new HashSet<String>(Arrays.asList(array));
Set does not allow duplicates.
Finally the set contains yes and no(only 2 elements)
If this is your array
String[] a = {"yes","yes","yes","yes","no","no","no","no"};
then this will display unique values
System.out.println(new HashSet(Arrays.asList(a)));
Dump your array into a set and use that:
Set uniqueStrings = new HashSet(Arrays.asList(yourArray));
If you need it as array again you can use
String[] uniqueStringsArray = uniqueStrings.toArray(new String[uniqueStrings.size()]);
Internally, this iterates through the array and compares the Strings. You cannot avoid that.
Try some thing like this
String[] arr=new String[]{"yes","yes","yes","yes","no","no","no","no"};
Object[] unique = new HashSet<>(Arrays.asList(arr)).toArray();
System.out.println(unique[0]);
System.out.println(unique[1]);