Update lists through lambda [duplicate] - java

I have an ArrayList<String>, and I want to remove repeated strings from it. How can I do this?

If you don't want duplicates in a Collection, you should consider why you're using a Collection that allows duplicates. The easiest way to remove repeated elements is to add the contents to a Set (which will not allow duplicates) and then add the Set back to the ArrayList:
Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);
Of course, this destroys the ordering of the elements in the ArrayList.

Although converting the ArrayList to a HashSet effectively removes duplicates, if you need to preserve insertion order, I'd rather suggest you to use this variant
// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);
Then, if you need to get back a List reference, you can use again the conversion constructor.

In Java 8:
List<String> deduped = list.stream().distinct().collect(Collectors.toList());
Please note that the hashCode-equals contract for list members should be respected for the filtering to work properly.

Suppose we have a list of String like:
List<String> strList = new ArrayList<>(5);
// insert up to five items to list.
Then we can remove duplicate elements in multiple ways.
Prior to Java 8
List<String> deDupStringList = new ArrayList<>(new HashSet<>(strList));
Note: If we want to maintain the insertion order then we need to use LinkedHashSet in place of HashSet
Using Guava
List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));
Using Java 8
List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());
Note: In case we want to collect the result in a specific list implementation e.g. LinkedList then we can modify the above example as:
List<String> deDupStringList3 = strList.stream().distinct()
.collect(Collectors.toCollection(LinkedList::new));
We can use parallelStream also in the above code but it may not give expected performace benefits. Check this question for more.

If you don't want duplicates, use a Set instead of a List. To convert a List to a Set you can use the following code:
// list is some List of Strings
Set<String> s = new HashSet<String>(list);
If really necessary you can use the same construction to convert a Set back into a List.

Java 8 streams provide a very simple way to remove duplicate elements from a list. Using the distinct method.
If we have a list of cities and we want to remove duplicates from that list it can be done in a single line -
List<String> cityList = new ArrayList<>();
cityList.add("Delhi");
cityList.add("Mumbai");
cityList.add("Bangalore");
cityList.add("Chennai");
cityList.add("Kolkata");
cityList.add("Mumbai");
cityList = cityList.stream().distinct().collect(Collectors.toList());
How to remove duplicate elements from an arraylist

You can also do it this way, and preserve order:
// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList<String>(new LinkedHashSet<String>(myArrayList));

Here's a way that doesn't affect your list ordering:
ArrayList l1 = new ArrayList();
ArrayList l2 = new ArrayList();
Iterator iterator = l1.iterator();
while (iterator.hasNext()) {
YourClass o = (YourClass) iterator.next();
if(!l2.contains(o)) l2.add(o);
}
l1 is the original list, and l2 is the list without repeated items
(Make sure YourClass has the equals method according to what you want to stand for equality)

this can solve the problem:
private List<SomeClass> clearListFromDuplicateFirstName(List<SomeClass> list1) {
Map<String, SomeClass> cleanMap = new LinkedHashMap<String, SomeClass>();
for (int i = 0; i < list1.size(); i++) {
cleanMap.put(list1.get(i).getFirstName(), list1.get(i));
}
List<SomeClass> list = new ArrayList<SomeClass>(cleanMap.values());
return list;
}

It is possible to remove duplicates from arraylist without using HashSet or one more arraylist.
Try this code..
ArrayList<String> lst = new ArrayList<String>();
lst.add("ABC");
lst.add("ABC");
lst.add("ABCD");
lst.add("ABCD");
lst.add("ABCE");
System.out.println("Duplicates List "+lst);
Object[] st = lst.toArray();
for (Object s : st) {
if (lst.indexOf(s) != lst.lastIndexOf(s)) {
lst.remove(lst.lastIndexOf(s));
}
}
System.out.println("Distinct List "+lst);
Output is
Duplicates List [ABC, ABC, ABCD, ABCD, ABCE]
Distinct List [ABC, ABCD, ABCE]

There is also ImmutableSet from Guava as an option (here is the documentation):
ImmutableSet.copyOf(list);

Probably a bit overkill, but I enjoy this kind of isolated problem. :)
This code uses a temporary Set (for the uniqueness check) but removes elements directly inside the original list. Since element removal inside an ArrayList can induce a huge amount of array copying, the remove(int)-method is avoided.
public static <T> void removeDuplicates(ArrayList<T> list) {
int size = list.size();
int out = 0;
{
final Set<T> encountered = new HashSet<T>();
for (int in = 0; in < size; in++) {
final T t = list.get(in);
final boolean first = encountered.add(t);
if (first) {
list.set(out++, t);
}
}
}
while (out < size) {
list.remove(--size);
}
}
While we're at it, here's a version for LinkedList (a lot nicer!):
public static <T> void removeDuplicates(LinkedList<T> list) {
final Set<T> encountered = new HashSet<T>();
for (Iterator<T> iter = list.iterator(); iter.hasNext(); ) {
final T t = iter.next();
final boolean first = encountered.add(t);
if (!first) {
iter.remove();
}
}
}
Use the marker interface to present a unified solution for List:
public static <T> void removeDuplicates(List<T> list) {
if (list instanceof RandomAccess) {
// use first version here
} else {
// use other version here
}
}
EDIT: I guess the generics-stuff doesn't really add any value here.. Oh well. :)

public static void main(String[] args){
ArrayList<Object> al = new ArrayList<Object>();
al.add("abc");
al.add('a');
al.add('b');
al.add('a');
al.add("abc");
al.add(10.3);
al.add('c');
al.add(10);
al.add("abc");
al.add(10);
System.out.println("Before Duplicate Remove:"+al);
for(int i=0;i<al.size();i++){
for(int j=i+1;j<al.size();j++){
if(al.get(i).equals(al.get(j))){
al.remove(j);
j--;
}
}
}
System.out.println("After Removing duplicate:"+al);
}

If you're willing to use a third-party library, you can use the method distinct() in Eclipse Collections (formerly GS Collections).
ListIterable<Integer> integers = FastList.newListWith(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
FastList.newListWith(1, 3, 2),
integers.distinct());
The advantage of using distinct() instead of converting to a Set and then back to a List is that distinct() preserves the order of the original List, retaining the first occurrence of each element. It's implemented by using both a Set and a List.
MutableSet<T> seenSoFar = UnifiedSet.newSet();
int size = list.size();
for (int i = 0; i < size; i++)
{
T item = list.get(i);
if (seenSoFar.add(item))
{
targetCollection.add(item);
}
}
return targetCollection;
If you cannot convert your original List into an Eclipse Collections type, you can use ListAdapter to get the same API.
MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();
Note: I am a committer for Eclipse Collections.

If you are using model type List< T>/ArrayList< T> . Hope,it's help you.
Here is my code without using any other data structure like set or hashmap
for (int i = 0; i < Models.size(); i++){
for (int j = i + 1; j < Models.size(); j++) {
if (Models.get(i).getName().equals(Models.get(j).getName())) {
Models.remove(j);
j--;
}
}
}

If you want to preserve your Order then it is best to use LinkedHashSet.
Because if you want to pass this List to an Insert Query by Iterating it, the order would be preserved.
Try this
LinkedHashSet link=new LinkedHashSet();
List listOfValues=new ArrayList();
listOfValues.add(link);
This conversion will be very helpful when you want to return a List but not a Set.

This three lines of code can remove the duplicated element from ArrayList or any collection.
List<Entity> entities = repository.findByUserId(userId);
Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);

for(int a=0;a<myArray.size();a++){
for(int b=a+1;b<myArray.size();b++){
if(myArray.get(a).equalsIgnoreCase(myArray.get(b))){
myArray.remove(b);
dups++;
b--;
}
}
}

When you are filling the ArrayList, use a condition for each element. For example:
ArrayList< Integer > al = new ArrayList< Integer >();
// fill 1
for ( int i = 0; i <= 5; i++ )
if ( !al.contains( i ) )
al.add( i );
// fill 2
for (int i = 0; i <= 10; i++ )
if ( !al.contains( i ) )
al.add( i );
for( Integer i: al )
{
System.out.print( i + " ");
}
We will get an array {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

Code:
List<String> duplicatList = new ArrayList<String>();
duplicatList = Arrays.asList("AA","BB","CC","DD","DD","EE","AA","FF");
//above AA and DD are duplicate
Set<String> uniqueList = new HashSet<String>(duplicatList);
duplicatList = new ArrayList<String>(uniqueList); //let GC will doing free memory
System.out.println("Removed Duplicate : "+duplicatList);
Note: Definitely, there will be memory overhead.

ArrayList<String> city=new ArrayList<String>();
city.add("rajkot");
city.add("gondal");
city.add("rajkot");
city.add("gova");
city.add("baroda");
city.add("morbi");
city.add("gova");
HashSet<String> hashSet = new HashSet<String>();
hashSet.addAll(city);
city.clear();
city.addAll(hashSet);
Toast.makeText(getActivity(),"" + city.toString(),Toast.LENGTH_SHORT).show();

you can use nested loop in follow :
ArrayList<Class1> l1 = new ArrayList<Class1>();
ArrayList<Class1> l2 = new ArrayList<Class1>();
Iterator iterator1 = l1.iterator();
boolean repeated = false;
while (iterator1.hasNext())
{
Class1 c1 = (Class1) iterator1.next();
for (Class1 _c: l2) {
if(_c.getId() == c1.getId())
repeated = true;
}
if(!repeated)
l2.add(c1);
}

LinkedHashSet will do the trick.
String[] arr2 = {"5","1","2","3","3","4","1","2"};
Set<String> set = new LinkedHashSet<String>(Arrays.asList(arr2));
for(String s1 : set)
System.out.println(s1);
System.out.println( "------------------------" );
String[] arr3 = set.toArray(new String[0]);
for(int i = 0; i < arr3.length; i++)
System.out.println(arr3[i].toString());
//output: 5,1,2,3,4

List<String> result = new ArrayList<String>();
Set<String> set = new LinkedHashSet<String>();
String s = "ravi is a good!boy. But ravi is very nasty fellow.";
StringTokenizer st = new StringTokenizer(s, " ,. ,!");
while (st.hasMoreTokens()) {
result.add(st.nextToken());
}
System.out.println(result);
set.addAll(result);
result.clear();
result.addAll(set);
System.out.println(result);
output:
[ravi, is, a, good, boy, But, ravi, is, very, nasty, fellow]
[ravi, is, a, good, boy, But, very, nasty, fellow]

This is used for your Custom Objects list
public List<Contact> removeDuplicates(List<Contact> list) {
// Set set1 = new LinkedHashSet(list);
Set set = new TreeSet(new Comparator() {
#Override
public int compare(Object o1, Object o2) {
if (((Contact) o1).getId().equalsIgnoreCase(((Contact) o2).getId()) /*&&
((Contact)o1).getName().equalsIgnoreCase(((Contact)o2).getName())*/) {
return 0;
}
return 1;
}
});
set.addAll(list);
final List newList = new ArrayList(set);
return newList;
}

As said before, you should use a class implementing the Set interface instead of List to be sure of the unicity of elements. If you have to keep the order of elements, the SortedSet interface can then be used; the TreeSet class implements that interface.

import java.util.*;
class RemoveDupFrmString
{
public static void main(String[] args)
{
String s="appsc";
Set<Character> unique = new LinkedHashSet<Character> ();
for(char c : s.toCharArray()) {
System.out.println(unique.add(c));
}
for(char dis:unique){
System.out.println(dis);
}
}
}

public Set<Object> findDuplicates(List<Object> list) {
Set<Object> items = new HashSet<Object>();
Set<Object> duplicates = new HashSet<Object>();
for (Object item : list) {
if (items.contains(item)) {
duplicates.add(item);
} else {
items.add(item);
}
}
return duplicates;
}

ArrayList<String> list = new ArrayList<String>();
HashSet<String> unique = new LinkedHashSet<String>();
HashSet<String> dup = new LinkedHashSet<String>();
boolean b = false;
list.add("Hello");
list.add("Hello");
list.add("how");
list.add("are");
list.add("u");
list.add("u");
for(Iterator iterator= list.iterator();iterator.hasNext();)
{
String value = (String)iterator.next();
System.out.println(value);
if(b==unique.add(value))
dup.add(value);
else
unique.add(value);
}
System.out.println(unique);
System.out.println(dup);

If you want to remove duplicates from ArrayList means find the below logic,
public static Object[] removeDuplicate(Object[] inputArray)
{
long startTime = System.nanoTime();
int totalSize = inputArray.length;
Object[] resultArray = new Object[totalSize];
int newSize = 0;
for(int i=0; i<totalSize; i++)
{
Object value = inputArray[i];
if(value == null)
{
continue;
}
for(int j=i+1; j<totalSize; j++)
{
if(value.equals(inputArray[j]))
{
inputArray[j] = null;
}
}
resultArray[newSize++] = value;
}
long endTime = System.nanoTime()-startTime;
System.out.println("Total Time-B:"+endTime);
return resultArray;
}

Related

How to interleave two arrays into a new array

Creates a new List that holds the elements of list1 interleaved
with the elements of list2. For example, if list1 holds
<"over","river","through","woods"> and list2 holds <"the","and","the">,
then the new list should hold
<"over","the","river","and","through","the","woods">. Alternating between
list1 and list2. If one list is longer, the new list will contain all of
the extra values from the longer list at the end. For example, if list1
holds <"over","river","through","woods"> and list2 holds <"the","and">
then the new list should hold
<"over","the","river","and","through","woods">.
I suck at programing and can't see the logic on the last part of this assignment. Thank you for taking the time to look at this.
//*
private static List<String> mergeLists(List<String> list1, List<String> list2) {
long max = Math.max(((File) list1).length(),((File) list2).length());
ArrayList<String> newlist = new ArrayList<String>();
for (int i = 0; i < max; i++) {
if (i < list1) {
newlist.append(list1[i]);
{
if (i < list2) {
newlist.append(list2[i]);
}
}
return newlist;
}
}
}
You definitely had the right idea, you almost got it. Guess you don't suck at programming that much :). You can use properties of a List for this, without casting to a File.
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("over");
list1.add("river");
list1.add("through");
list1.add("woods");
List<String> list2 = new ArrayList<>();
list2.add("the");
list2.add("and");
mergeLists(list1, list2);
}
private static List<String> mergeLists(List<String> list1, List<String> list2) {
// Get the max length of both arrays
int max = Math.max(list1.size(), list2.size());
// Initialize new list
List<String> newList = new ArrayList<>();
// add an element of the first list to the new list (if there are more elements)
// and then add an element from the second list to the new list (if there are more elements)
// and repeat...
for (int i = 0; i < max; i++) {
if (i < list1.size()) {
newList.add(list1.get(i));
}
if (i < list2.size()) {
newList.add(list2.get(i));
}
}
System.out.println(newList);
return newList;
}

Arraylist remove

Need to do a method which takes ArrayList<ArrayList<<Integer>> and an Integer which then returns an ArrayList<ArrayList<<Integer>> from the orginal ArrayList<ArrayList<<Integer>> which do not contain the Integer argument e.g
ArrayList<ArrayList<<Integer>>
[[1,2,3],[7,5],[4,4,2],[8,12,3]] and Integer 2 should return
[[7,5],[8,12,3]]. arraylist of arraylist integers.
not entirely sure how to access the inner loop
You can use contains() rather than worrying about writing an inner loop yourself.
Also, removing elements from lists while iterating is tricky. So, since you are not modifying the list and seem to be expected to return one, then just make a new list and add rather than remove.
public static ArrayList<ArrayList<Integer>> removeTheNumber(ArrayList<ArrayList<Integer>> n , Integer p){
ArrayList<ArrayList<Integer>> a = new ArrayList<>();
for(int i=0; i < n.size(); i++){
ArrayList<Integer> innerList = n.get(i);
if (!innerList.contains(p)) a.add(innerList);
}
return a;
}
You can use .contains of the inner lists to check as Integer class supports this. Below is a function and its test.
public ArrayList<ArrayList<Integer>> removeTheNumber(ArrayList<ArrayList<Integer>> lists, Integer n) {
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
for (ArrayList<Integer> list: lists ) {
if (!list.contains(n))
result.add(list);
}
return result;
}
#Test
public void testRemoveNumber() {
ArrayList<ArrayList<Integer>> lists = new ArrayList<>();
lists.add(Lists.newArrayList(2,7,8));
lists.add(Lists.newArrayList(6,7,9));
lists.add(Lists.newArrayList(3,2,6));
ArrayList<ArrayList<Integer>> result = removeTheNumber(lists, 2);
Assert.assertArrayEquals(lists.get(1).toArray(new Integer[]{}), result.get(0).toArray(new Integer[]{}));
result = removeTheNumber(lists, 7);
Assert.assertArrayEquals(lists.get(2).toArray(new Integer[]{}), result.get(0).toArray(new Integer[]{}));
result = removeTheNumber(lists, 6);
Assert.assertArrayEquals(lists.get(0).toArray(new Integer[]{}), result.get(0).toArray(new Integer[]{}));
}
If you want to use two loops you can write it like this (where array is your input array, and toSearch is your integer):
ArrayList<ArrayList<Integer>> arrayToReturn = new ArrayList<>();
for(ArrayList<Integer> listInner : array){
boolean found = false;
for(Integer elem : listInner) {
if (elem == toSearch)
found=true;
}
if(found!=true)
arrayToReturn.add(listInner);
}
arrayToReturn.stream().forEach(System.out::println);
Of course i reccomend to use java 8, and then you can simply write it like this:
arrayToReturn = array.stream().filter(elem ->
!elem.contains(toSearch)).collect(
Collectors.toCollection(ArrayList<ArrayList<Integer>>::new));
arrayToReturn.stream().forEach(System.out::println);
Let's pretend you have
ArrayList<ArrayList<Integer>> myArrayList = [[1,2,3],[7,5],[4,4,2],[8,12,3]];
for (int i = 0; i < myArrayList.length; i++) {
//...
}
Your variable i is iterating through the initial ArrayList, which contains another ArrayList. So, myArrayList[i] will yield another ArrayList, which also has a length.
Building on this we have:
for (int i = 0; i < myArrayList.length; i++) {
ArrayList<Integer> inner = myArrayList.get(i);
for (int j = 0; j < inner.length; j++) {
//now we may check for the existence of our integer
}
}

Modify String objects in a static array

I want to make a for-loop to add a letter to each string object in my list. I'm just not sure how to edit the objects in the list and not the actual list.
for instance, if I wanted to add "ing" to the end of each object in my list..
I feel like it's something simple, but I've been looking through oracle forever and haven't been able to figure it out if anyone can point me in the right direction?
I could use any kind of list really.. just anything that works.
I was thinking something like,
String[] stringArray = tools.toArray(new String[0]);
for (int i = 0; i < stringArray.length; i++)
{
stringArray[i] = stringArray[i].*part that would modify would go here*
}
You cannot edit a String. They are immutable. However, you can replace the entry in the list.
ArrayList<String> list = new ArrayList<>();
list.add("load");
list.add("pull");
for (int i = 0; i < list.size(); ++i) {
list.set(i, list.get(i) + "ing");
You updated your question to specify a static array:
stringArray[i] = stringArray[i] + "ing";
The right side of the assignment is performing a String concatenation which can be done with the + operator in Java.
You can use StringBuilder for this purpose.
public static void addIng(String[] arr) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
sb.setLength(0);
sb.append(arr[i] + "ing");
arr[i] = sb.toString();
}
}
Strings are immutable in java; they can't be modified once created.
Here it seems you have a few options; you can create a method that takes your list and returns a new list, by appending 'ing' to the end of each string in the list.
Alternatively, if you need to keep a reference to the original list, you can loop over the contents of the list (ArrayList?) and pop each string out, create a new string with the appended 'ing', and replace in the list.
Something like
List<String> list = new ArrayList<>();
list.add("testing");
for(String s:list){
s=s+"ing";
}
Please take a look below samples.
//Java 8 code.
List<String> oldList = Arrays.asList("a", "b");
List<String> newList = oldList.stream().map(str -> new StringBuilder(str).append("ing").toString()).collect(Collectors.toList());
System.out.println(oldList); // [a, b]
System.out.println(newList); // [aing, bing]
// Java 7 or below.
List<String> oldList = Arrays.asList("a", "b");
List<String> newList = new LinkedList<String>();
for (String str : oldList) {
newList.add(new StringBuilder(str).append("ing").toString());
}
System.out.println(oldList); // [a, b]
System.out.println(newList); // [aing, bing]

Remove duplicates from ArrayList in Java [duplicate]

I have an ArrayList<String>, and I want to remove repeated strings from it. How can I do this?
If you don't want duplicates in a Collection, you should consider why you're using a Collection that allows duplicates. The easiest way to remove repeated elements is to add the contents to a Set (which will not allow duplicates) and then add the Set back to the ArrayList:
Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);
Of course, this destroys the ordering of the elements in the ArrayList.
Although converting the ArrayList to a HashSet effectively removes duplicates, if you need to preserve insertion order, I'd rather suggest you to use this variant
// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);
Then, if you need to get back a List reference, you can use again the conversion constructor.
In Java 8:
List<String> deduped = list.stream().distinct().collect(Collectors.toList());
Please note that the hashCode-equals contract for list members should be respected for the filtering to work properly.
Suppose we have a list of String like:
List<String> strList = new ArrayList<>(5);
// insert up to five items to list.
Then we can remove duplicate elements in multiple ways.
Prior to Java 8
List<String> deDupStringList = new ArrayList<>(new HashSet<>(strList));
Note: If we want to maintain the insertion order then we need to use LinkedHashSet in place of HashSet
Using Guava
List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));
Using Java 8
List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());
Note: In case we want to collect the result in a specific list implementation e.g. LinkedList then we can modify the above example as:
List<String> deDupStringList3 = strList.stream().distinct()
.collect(Collectors.toCollection(LinkedList::new));
We can use parallelStream also in the above code but it may not give expected performace benefits. Check this question for more.
If you don't want duplicates, use a Set instead of a List. To convert a List to a Set you can use the following code:
// list is some List of Strings
Set<String> s = new HashSet<String>(list);
If really necessary you can use the same construction to convert a Set back into a List.
Java 8 streams provide a very simple way to remove duplicate elements from a list. Using the distinct method.
If we have a list of cities and we want to remove duplicates from that list it can be done in a single line -
List<String> cityList = new ArrayList<>();
cityList.add("Delhi");
cityList.add("Mumbai");
cityList.add("Bangalore");
cityList.add("Chennai");
cityList.add("Kolkata");
cityList.add("Mumbai");
cityList = cityList.stream().distinct().collect(Collectors.toList());
How to remove duplicate elements from an arraylist
You can also do it this way, and preserve order:
// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList<String>(new LinkedHashSet<String>(myArrayList));
Here's a way that doesn't affect your list ordering:
ArrayList l1 = new ArrayList();
ArrayList l2 = new ArrayList();
Iterator iterator = l1.iterator();
while (iterator.hasNext()) {
YourClass o = (YourClass) iterator.next();
if(!l2.contains(o)) l2.add(o);
}
l1 is the original list, and l2 is the list without repeated items
(Make sure YourClass has the equals method according to what you want to stand for equality)
this can solve the problem:
private List<SomeClass> clearListFromDuplicateFirstName(List<SomeClass> list1) {
Map<String, SomeClass> cleanMap = new LinkedHashMap<String, SomeClass>();
for (int i = 0; i < list1.size(); i++) {
cleanMap.put(list1.get(i).getFirstName(), list1.get(i));
}
List<SomeClass> list = new ArrayList<SomeClass>(cleanMap.values());
return list;
}
It is possible to remove duplicates from arraylist without using HashSet or one more arraylist.
Try this code..
ArrayList<String> lst = new ArrayList<String>();
lst.add("ABC");
lst.add("ABC");
lst.add("ABCD");
lst.add("ABCD");
lst.add("ABCE");
System.out.println("Duplicates List "+lst);
Object[] st = lst.toArray();
for (Object s : st) {
if (lst.indexOf(s) != lst.lastIndexOf(s)) {
lst.remove(lst.lastIndexOf(s));
}
}
System.out.println("Distinct List "+lst);
Output is
Duplicates List [ABC, ABC, ABCD, ABCD, ABCE]
Distinct List [ABC, ABCD, ABCE]
There is also ImmutableSet from Guava as an option (here is the documentation):
ImmutableSet.copyOf(list);
Probably a bit overkill, but I enjoy this kind of isolated problem. :)
This code uses a temporary Set (for the uniqueness check) but removes elements directly inside the original list. Since element removal inside an ArrayList can induce a huge amount of array copying, the remove(int)-method is avoided.
public static <T> void removeDuplicates(ArrayList<T> list) {
int size = list.size();
int out = 0;
{
final Set<T> encountered = new HashSet<T>();
for (int in = 0; in < size; in++) {
final T t = list.get(in);
final boolean first = encountered.add(t);
if (first) {
list.set(out++, t);
}
}
}
while (out < size) {
list.remove(--size);
}
}
While we're at it, here's a version for LinkedList (a lot nicer!):
public static <T> void removeDuplicates(LinkedList<T> list) {
final Set<T> encountered = new HashSet<T>();
for (Iterator<T> iter = list.iterator(); iter.hasNext(); ) {
final T t = iter.next();
final boolean first = encountered.add(t);
if (!first) {
iter.remove();
}
}
}
Use the marker interface to present a unified solution for List:
public static <T> void removeDuplicates(List<T> list) {
if (list instanceof RandomAccess) {
// use first version here
} else {
// use other version here
}
}
EDIT: I guess the generics-stuff doesn't really add any value here.. Oh well. :)
public static void main(String[] args){
ArrayList<Object> al = new ArrayList<Object>();
al.add("abc");
al.add('a');
al.add('b');
al.add('a');
al.add("abc");
al.add(10.3);
al.add('c');
al.add(10);
al.add("abc");
al.add(10);
System.out.println("Before Duplicate Remove:"+al);
for(int i=0;i<al.size();i++){
for(int j=i+1;j<al.size();j++){
if(al.get(i).equals(al.get(j))){
al.remove(j);
j--;
}
}
}
System.out.println("After Removing duplicate:"+al);
}
If you're willing to use a third-party library, you can use the method distinct() in Eclipse Collections (formerly GS Collections).
ListIterable<Integer> integers = FastList.newListWith(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
FastList.newListWith(1, 3, 2),
integers.distinct());
The advantage of using distinct() instead of converting to a Set and then back to a List is that distinct() preserves the order of the original List, retaining the first occurrence of each element. It's implemented by using both a Set and a List.
MutableSet<T> seenSoFar = UnifiedSet.newSet();
int size = list.size();
for (int i = 0; i < size; i++)
{
T item = list.get(i);
if (seenSoFar.add(item))
{
targetCollection.add(item);
}
}
return targetCollection;
If you cannot convert your original List into an Eclipse Collections type, you can use ListAdapter to get the same API.
MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();
Note: I am a committer for Eclipse Collections.
If you are using model type List< T>/ArrayList< T> . Hope,it's help you.
Here is my code without using any other data structure like set or hashmap
for (int i = 0; i < Models.size(); i++){
for (int j = i + 1; j < Models.size(); j++) {
if (Models.get(i).getName().equals(Models.get(j).getName())) {
Models.remove(j);
j--;
}
}
}
If you want to preserve your Order then it is best to use LinkedHashSet.
Because if you want to pass this List to an Insert Query by Iterating it, the order would be preserved.
Try this
LinkedHashSet link=new LinkedHashSet();
List listOfValues=new ArrayList();
listOfValues.add(link);
This conversion will be very helpful when you want to return a List but not a Set.
This three lines of code can remove the duplicated element from ArrayList or any collection.
List<Entity> entities = repository.findByUserId(userId);
Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);
for(int a=0;a<myArray.size();a++){
for(int b=a+1;b<myArray.size();b++){
if(myArray.get(a).equalsIgnoreCase(myArray.get(b))){
myArray.remove(b);
dups++;
b--;
}
}
}
When you are filling the ArrayList, use a condition for each element. For example:
ArrayList< Integer > al = new ArrayList< Integer >();
// fill 1
for ( int i = 0; i <= 5; i++ )
if ( !al.contains( i ) )
al.add( i );
// fill 2
for (int i = 0; i <= 10; i++ )
if ( !al.contains( i ) )
al.add( i );
for( Integer i: al )
{
System.out.print( i + " ");
}
We will get an array {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Code:
List<String> duplicatList = new ArrayList<String>();
duplicatList = Arrays.asList("AA","BB","CC","DD","DD","EE","AA","FF");
//above AA and DD are duplicate
Set<String> uniqueList = new HashSet<String>(duplicatList);
duplicatList = new ArrayList<String>(uniqueList); //let GC will doing free memory
System.out.println("Removed Duplicate : "+duplicatList);
Note: Definitely, there will be memory overhead.
ArrayList<String> city=new ArrayList<String>();
city.add("rajkot");
city.add("gondal");
city.add("rajkot");
city.add("gova");
city.add("baroda");
city.add("morbi");
city.add("gova");
HashSet<String> hashSet = new HashSet<String>();
hashSet.addAll(city);
city.clear();
city.addAll(hashSet);
Toast.makeText(getActivity(),"" + city.toString(),Toast.LENGTH_SHORT).show();
you can use nested loop in follow :
ArrayList<Class1> l1 = new ArrayList<Class1>();
ArrayList<Class1> l2 = new ArrayList<Class1>();
Iterator iterator1 = l1.iterator();
boolean repeated = false;
while (iterator1.hasNext())
{
Class1 c1 = (Class1) iterator1.next();
for (Class1 _c: l2) {
if(_c.getId() == c1.getId())
repeated = true;
}
if(!repeated)
l2.add(c1);
}
LinkedHashSet will do the trick.
String[] arr2 = {"5","1","2","3","3","4","1","2"};
Set<String> set = new LinkedHashSet<String>(Arrays.asList(arr2));
for(String s1 : set)
System.out.println(s1);
System.out.println( "------------------------" );
String[] arr3 = set.toArray(new String[0]);
for(int i = 0; i < arr3.length; i++)
System.out.println(arr3[i].toString());
//output: 5,1,2,3,4
List<String> result = new ArrayList<String>();
Set<String> set = new LinkedHashSet<String>();
String s = "ravi is a good!boy. But ravi is very nasty fellow.";
StringTokenizer st = new StringTokenizer(s, " ,. ,!");
while (st.hasMoreTokens()) {
result.add(st.nextToken());
}
System.out.println(result);
set.addAll(result);
result.clear();
result.addAll(set);
System.out.println(result);
output:
[ravi, is, a, good, boy, But, ravi, is, very, nasty, fellow]
[ravi, is, a, good, boy, But, very, nasty, fellow]
This is used for your Custom Objects list
public List<Contact> removeDuplicates(List<Contact> list) {
// Set set1 = new LinkedHashSet(list);
Set set = new TreeSet(new Comparator() {
#Override
public int compare(Object o1, Object o2) {
if (((Contact) o1).getId().equalsIgnoreCase(((Contact) o2).getId()) /*&&
((Contact)o1).getName().equalsIgnoreCase(((Contact)o2).getName())*/) {
return 0;
}
return 1;
}
});
set.addAll(list);
final List newList = new ArrayList(set);
return newList;
}
As said before, you should use a class implementing the Set interface instead of List to be sure of the unicity of elements. If you have to keep the order of elements, the SortedSet interface can then be used; the TreeSet class implements that interface.
import java.util.*;
class RemoveDupFrmString
{
public static void main(String[] args)
{
String s="appsc";
Set<Character> unique = new LinkedHashSet<Character> ();
for(char c : s.toCharArray()) {
System.out.println(unique.add(c));
}
for(char dis:unique){
System.out.println(dis);
}
}
}
public Set<Object> findDuplicates(List<Object> list) {
Set<Object> items = new HashSet<Object>();
Set<Object> duplicates = new HashSet<Object>();
for (Object item : list) {
if (items.contains(item)) {
duplicates.add(item);
} else {
items.add(item);
}
}
return duplicates;
}
ArrayList<String> list = new ArrayList<String>();
HashSet<String> unique = new LinkedHashSet<String>();
HashSet<String> dup = new LinkedHashSet<String>();
boolean b = false;
list.add("Hello");
list.add("Hello");
list.add("how");
list.add("are");
list.add("u");
list.add("u");
for(Iterator iterator= list.iterator();iterator.hasNext();)
{
String value = (String)iterator.next();
System.out.println(value);
if(b==unique.add(value))
dup.add(value);
else
unique.add(value);
}
System.out.println(unique);
System.out.println(dup);
If you want to remove duplicates from ArrayList means find the below logic,
public static Object[] removeDuplicate(Object[] inputArray)
{
long startTime = System.nanoTime();
int totalSize = inputArray.length;
Object[] resultArray = new Object[totalSize];
int newSize = 0;
for(int i=0; i<totalSize; i++)
{
Object value = inputArray[i];
if(value == null)
{
continue;
}
for(int j=i+1; j<totalSize; j++)
{
if(value.equals(inputArray[j]))
{
inputArray[j] = null;
}
}
resultArray[newSize++] = value;
}
long endTime = System.nanoTime()-startTime;
System.out.println("Total Time-B:"+endTime);
return resultArray;
}

Efficient way to get indexes of matched items using Lists

I've two lists A and B. I'd like to find out indexes of elements in A that match elements of listB. Something like this:
ArrayList listA = new ArrayList();
listA.add(1);listA.add(2);listA.add(3);listA.add(4);
ArrayList listB = new ArrayList();
listB.add(2);listB.add(4);
ArrayList listC = new ArrayList();
for(int i=0; i<listB.size();i++) {
int element = listB.get(i);
for(int j=0; j<listA.size(); j++) {
if(listA.get(j) == element) listC.add(j);
}
}
I guess that's one ugly way to doing it. What is the best way to finding all the indexes of A that match all elements in B? I believe there exists a method called containsAll in collections api - don't think it returns matching indexes.
If you had to use an ArrayList, you could create a HashSet from the ArrayList. This would make the call to contains O(1). It would take O(n) to create the HastSet. If you could start with a HashSet, that would be best.
public static void main(String[] args)
{
List listA = new ArrayList();
listA.add(1);
listA.add(2);
listA.add(3);
listA.add(4);
List listB = new ArrayList();
listB.add(2);
listB.add(4);
Set hashset = new HashSet(listA);
for(int i = 0; i < listB.size(); i++)
{
if(hashset.contains(listB.get(i)))
{
listC.add(i);
System.out.println(i);
}
}
}
The Guava libraries come with a method
"SetView com.google.common.collect.Sets.intersection(Set a, Set b)
that will give the elements contained in both sets, but not the indexes. Although it should be easy to get the indexes afterwards.
Simple:
List<Integer> listA = new ArrayList<Integer>();
listA.add(1);
listA.add(2);
listA.add(3);
listA.add(4);
List<Integer> listB = new ArrayList<Integer>();
listB.add(2);
listB.add(4);
List<Integer> listC = new ArrayList<Integer>();
for ( Integer item : listA ) {
int index = listB.indexOf( item );
if ( index >= 0 ) {
listC.add(index);
}
}
But this only works if there is no repetition, if there are repeated indexes you have to do it the way you did, navigating the full list.
EDIT
I thought you wanted the elements, not indexes, sets are not going to give you indexes, only the elements.
Assuming there's no duplicate values, why not use ArrayList.indexOf?
public final class ArrayListDemo {
public static void main(String[]args){
findIndices(createListA(), createListB());
}
private static final List<Integer> createListA(){
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(3);
list.add(5);
return list;
}
private static final List<Integer> createListB(){
List<Integer> list = new ArrayList<Integer>();
list.add(0);
list.add(2);
list.add(3);
list.add(4);
return list;
}
private static void findIndices(List<Integer> listA, List<Integer> listB){
for(int i = 0; i < listA.size(); i++){
// Get index of object in list b
int index = listB.indexOf(listA.get(i));
// Check for match
if(index != -1){
System.out.println("Found match:");
System.out.println("List A index = " + i);
System.out.println("List B index = " + index);
}
}
}
}
Output
Found match:
List A index = 1
List B index = 2
If list A and list B are sorted in the same order (I'll assume ascending, but descending works as well) this problem has an O(n) solution. Below is some (informal, and untested) code. When the loop exits, indexMap should contain the indices of every element in list A that match an element in list B and the index of the matched element in list B.
int currentA;
int currentB;
int listAIndex = 0;
int listBIndex = 0;
Map<Integer, Integer> indexMap = new HashMap<Integer, Integer>();
currentA = listA.get(listAIndex);
currentB = listB.get(listBIndex);
while ((listAIndex < listA.length) && (listBIndex < listB.length))
{
if (currentA == currentB)
{
indexMap.put(listAIndex, listBIndex);
++listAIndex;
}
else if (currentA < currentB)
{
++listAIndex;
}
else // if (currentA > currentB)
{
++listBIndex;
}
}
Using Apache CollectionUtils, there are plenty of options

Categories

Resources