Removing duplicates in an ArrayList using Generics - java

I was asked to write a small program to remove the duplicates from a list and make a new list without the duplicates. We had to do this using Generics in Java. This is what I have so far:
All help is greatly appreciated!!!
import java.util.ArrayList;
public class Assignment13 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("one");
list.add("one");
list.add("two");
list.add("three");
list.add("three");
System.out.println("Prior to removal: " + list);
System.out.println("after: " + list2);
}
public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list) {
ArrayList<E> list2 = new ArrayList<E>();
for (int i = 1; i < list2.size(); i++) {
String a1 = list2.get(i);
String a2 = list2.get(i-1);
if (a1.equals(a2)) {
list2.remove(a1);
}
}
return list2;
}
}

This is the algorithm:
public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list) {
ArrayList<E> list2 = new ArrayList<E>();
for (E elem : list)
if (!list2.contains(elem))
list2.add(elem);
return list2;
}

You can achieve this with a loop and a condition:
public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list) {
ArrayList<E> list2 = new ArrayList<E>();
for(E item : list) {
if(!list2.contains(item)) {
list2.add(item);
}
}
return list2;
}

Using a Set (if allowed in your assignment) is more efficient than checking list.contains on each item. Ex:
public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list) {
Set<E> uniques = new HashSet<E>();
uniques.addAll(list);
return new ArrayList<E>(uniques);
}

The general strategy here is that you want to maintain a context as you traverse the list, and at each step, you use that piece of context to answer the question of whether the current item should be kept or thrown out. In pseudo-code:
public static <A> List<A> removeDuplicates(List<? extends A> original) {
List<A> result = new ArrayList<A>();
/* initialize context */
for (A item : original) {
if ( /* context says item is not a duplicate */ ) {
result.add(item);
}
/* update context to incorporate the current `item` */
}
return result;
}
Some people have brought up the question of whether you mean consecutive duplicates or non-consecutive ones. In reality, the difference in the solutions is small:
For consecutive duplicates the context is the most recently seen item.
For non-consecutive it's the Set<A> of all items seen up to that point.
I'll let you fill in the pattern for those cases.

From your question it seems that there is no guarantee that duplicated elements in the original list must appear in sequence. This means that checking if two adjacent elements are equal is not sufficient to remove all duplicates.
Checking adjacent elements would work if the list was sorted. But since you need to use generics, I suppose you are not allowed to make assumptions about the nature of the elements. This means you cannot sort the list, because you would need to know that the elements were Comparable.
So you can do it like this:
1. Create a new empty list
2. For each element in the original list
2.1 If the element is not in the new list, add it
2.2 Else, ignore it
If you are allowed to use Java 8, this is much easier:
static <E> List<E> removeDuplicates(List<E> list) {
return list.stream().distinct().collect(Collectors.toList());
}

Updated for your question
ArrayList<E> list2 = new ArrayList<E>();
for (int i = 1; i < list.size(); i++) {
String a1 = list2.get(i);
if (!list2.contains(a1)) {
list2.add(a1);
}
}

Related

Why am I getting an incompatible type error when using the List Iterator's next method but not when I use List's get method?

public static void main(String args[])
{
ArrayList<String> names = new ArrayList<String>();
names.add("Brett");
ArrayList<String> names2 = new ArrayList<String>();
names2.add("John");
append(names, names2);
}
public static <E> void append(List<E> list1, List<E> list2)
{
Iterator list2Iterator = list2.listIterator();
while(list2Iterator.hasNext())
{
list1.add(list2Iterator.next());
}
}
I was asked to append the elements of one list to another. I used the list2's iterator to retrieve each element, and passed them to list1's add method. But I got this error: incompatible types: Object cannot be converted to E. However, if I modify the append method:
public static <E> void append(List<E> list1, List<E> list2)
{
for (int i = 0; i < list2.size(); i++)
list1.add(list2.get(i));
}
it works just fine. Both the list iterator and the get method return the same type, but only the latter works. I'm sure the reason is simple, I just haven't figured it out so far.
Thanks,
The problem is that in your code you are loosing the type parameter when you obtain the list iterator.
public static <E> void append(List<E> list1, List<E> list2) {
Iterator<E> list2Iterator = list2.listIterator();
while(list2Iterator.hasNext()) {
list1.add(list2Iterator.next());
}
}
But you should avoid manually adding all elements of a collections 1 by 1 to another collection. Here is a better solution:
list1.addAll(list2);

Deleting duplicate elements in an ArrayList Java

Hi and thanks for reading! I'm currently studying Generics in Java and this is what I'm trying to accomplish:
I need to delete duplicate elements from an ArrayList. Currently, the ArrayList contains integers. I want to first print the original list, and then print the resulting list after removing the duplicates. This is what I have so far. Any help is appreciated!
public static void main(String[] args) {
ArrayList<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(1);
list1.add(1);
list1.add(2);
list1.add(2);
list1.add(2);
list1.add(3);
list1.add(3);
list1.add(3);
removeDuplicates(list1);
System.out.println("Original List with Duplicates: \n" + list1);
System.out.println();
//System.out.println("After removing duplicates: \n" + list2);
}
public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list2){
for(int i = 0; i < list2.size(); i++){
//logic to remove duplicates
}
return list2;
}
You could add the elements to the Set collection. If you want to preserve order you should use LinkedHashSet
Step One
Convert your list to a set.
Set<Integer> aSet = new HashSet<Integer>(list);
Step Two
Convert your set back to a list.
list = new ArrayList<Integer>(new HashSet<Integer>(list));
Why it Works
Sets can only contain unique elements.
public static void main(String[] args) {
ArrayList<Integer> list1 = new ArrayList<Integer>();
ArrayList<Integer> list2 = new ArrayList<Integer>();
list1.add(1);
list1.add(1);
list1.add(1);
list1.add(2);
list1.add(2);
list1.add(2);
list1.add(3);
list1.add(3);
list1.add(3);
System.out.println("Original List with Duplicates: \n" + list1);
System.out.println();
list2 = removeDuplicates(list1);
System.out.println("After removing duplicates: \n" + list2);
}
public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list2){
ArrayList<E> usedList = new ArrayList<E>();
ArrayList<E> newList = new ArrayList<E>();
for(int i = 0; i < list2.size(); i++){
E object = list2.get(i);
if(! usedList.contains(object))
{
usedList.add(object);
newList.add(object);
}
}
return newList;
}
Output (as expected):
Original List with Duplicates:
[1, 1, 1, 2, 2, 2, 3, 3, 3]
After removing duplicates:
[1, 2, 3]
If you're working with other types (not java standard like int), then you have to override the equals method, because it's used in the ArrayList contains method.
public static <E> ArrayList<E> removeDuplicates(ArrayList<E> list2){
LinkedHashSet<E> dataSet = new LinkedHashSet<E>(list2.size());
dataSet.addAll(list2);
ArrayList<E> uniqueLists = new ArrayList<E>(dataSet.size());
uniqueLists.addAll(dataSet);
return uniqueLists;
}
Convert the ArrayList to Set, maybe HashSet and then back to an ArrayList that you could sort if you want the numbers in order (the ordering in Sets are not usually not guaranteed).
HashSet hs<Integer> = new HashSet(list1);
ArrayList<Integer> uniqueList = Collections.sort(new ArrayList<Integer>(hs));
There's also various SortedSet, among them TreeSet.
Also, you can use a less error-prone for loop construction:
for (int i : uniqueList) {
System.out.println(i);
}
All the other answers so far create a new list. If you want to modify the list in place, you can iterate through the list while using an auxiliary Set to keep track of all elements already seen. The following works for any List (not just ArrayList) that allows elements to be removed:
public static <E> List<E> removeDuplicates(List<E> list){
ListIterator<E> iter = list.listIterator();
Set<E> seen = new HashSet<>();
while (iter.hasNext()) {
if (!seen.add(iter.next())) {
// element not added--must have already been seen, so remove element
iter.remove();
}
}
return list;
}
An alternative is to dump the entire list into a Set, clear the list, and then add all the element of the set back into the list. Depending on the Set implementation, this may or may not preserve order.
public static <E> List<E> removeDuplicates(List<E> list){
Set<E> unique = new LinkedHashSet<>(list);
list.clear();
list.addAll(unique);
return list;
}
EDIT: If (as per your comment) you wish to completely remove elements that are not unique to start with, you can modify the first approach:
public static <E> List<E> removeNonUnique(List<E> list){
Set<E> seen = new HashSet<>(); // all values seen
Set<E> dups = new HashSet<>(); // all values seen more than once
for (E elt : list) {
if (!seen.add(elt)) {
// element not added--must have already been seen, so add to dups
dups.add(elt);
}
}
// clean out the list
list.removeAll(dups);
return list;
}
Note that since we're not modifying the list during the loop, we don't need to have an explicit iterator.

How to have Java method return generic list of any type?

I would like to write a method that would return a java.util.List of any type without the need to typecast anything:
List<User> users = magicalListGetter(User.class);
List<Vehicle> vehicles = magicalListGetter(Vehicle.class);
List<String> strings = magicalListGetter(String.class);
What would the method signature look like? Something like this, perhaps(?):
public List<<?> ?> magicalListGetter(Class<?> clazz) {
List<?> list = doMagicalVooDooHere();
return list;
}
private Object actuallyT;
public <T> List<T> magicalListGetter(Class<T> klazz) {
List<T> list = new ArrayList<>();
list.add(klazz.cast(actuallyT));
try {
list.add(klazz.getConstructor().newInstance()); // If default constructor
} ...
return list;
}
One can give a generic type parameter to a method too. You have correctly deduced that one needs the correct class instance, to create things (klazz.getConstructor().newInstance()).
No need to even pass the class:
public <T> List<T> magicalListGetter() {
return new ArrayList<T>();
}
Another option is doing the following:
public class UserList extends List<User>{
}
public <T> T magicalListGetter(Class<T> clazz) {
List<?> list = doMagicalVooDooHere();
return (T)list;
}
List<User> users = magicalListGetter(UserList.class);
`
Let us have List<Object> objectList which we want to cast to List<T>
public <T> List<T> list(Class<T> c, List<Object> objectList){
List<T> list = new ArrayList<>();
for (Object o : objectList){
T t = c.cast(o);
list.add(t);
}
return list;
}
You can use the old way:
public List magicalListGetter() {
List list = doMagicalVooDooHere();
return list;
}
or you can use Object and the parent class of everything:
public List<Object> magicalListGetter() {
List<Object> list = doMagicalVooDooHere();
return list;
}
Note Perhaps there is a better parent class for all the objects you will put in the list. For example, Number would allow you to put Double and Integer in there.
Something like this
publiс <T> List<T> magicalListGetter(Class<T> clazz) {
List list = doMagicalVooDooHere();
return list;
}
You can simply cast to List and then check if every element can be casted to T.
public <T> List<T> asList(final Class<T> clazz) {
List<T> values = (List<T>) this.value;
values.forEach(clazz::cast);
return values;
}
Given some legacy code that returns an untyped List
List list = database.GetCustomers(); //legacy code returns untyped list
we will use a helper function:
public static <T> #NotNull List<T> castList(final #NotNull Iterable sourceList)
{
List<T> result = new ArrayList<>();
for (Object o : sourceList)
result.add((T)o);
return result;
}
to convert the returned list to a generic typed List<T>:
List<Customer> = castList(database.GetCustomers()); //cast the list the appropriate type
Why Java doesn't have extension methods is quite beyond me.
I'm pretty sure you can completely delete the <stuff> , which will generate a warning and you can use an, # suppress warnings. If you really want it to be generic, but to use any of its elements you will have to do type casting. For instance, I made a simple bubble sort function and it uses a generic type when sorting the list, which is actually an array of Comparable in this case. If you wish to use an item, do something like: System.out.println((Double)arrayOfDoubles[0] + (Double)arrayOfDoubles[1]); because I stuffed Double(s) into Comparable(s) which is polymorphism since all Double(s) inherit from Comparable to allow easy sorting through Collections.sort()
//INDENT TO DISPLAY CODE ON STACK-OVERFLOW
#SuppressWarnings("unchecked")
public static void simpleBubbleSort_ascending(#SuppressWarnings("rawtypes") Comparable[] arrayOfDoubles)
{
//VARS
//looping
int end = arrayOfDoubles.length - 1;//the last index in our loops
int iterationsMax = arrayOfDoubles.length - 1;
//swapping
#SuppressWarnings("rawtypes")
Comparable tempSwap = 0.0;//a temporary double used in the swap process
int elementP1 = 1;//element + 1, an index for comparing and swapping
//CODE
//do up to 'iterationsMax' many iterations
for (int iteration = 0; iteration < iterationsMax; iteration++)
{
//go through each element and compare it to the next element
for (int element = 0; element < end; element++)
{
elementP1 = element + 1;
//if the elements need to be swapped, swap them
if (arrayOfDoubles[element].compareTo(arrayOfDoubles[elementP1])==1)
{
//swap
tempSwap = arrayOfDoubles[element];
arrayOfDoubles[element] = arrayOfDoubles[elementP1];
arrayOfDoubles[elementP1] = tempSwap;
}
}
}
}//END public static void simpleBubbleSort_ascending(double[] arrayOfDoubles)

How to get a reversed list view on a list in Java?

I want to have a reversed list view on a list (in a similar way than List#sublist provides a sublist view on a list). Is there some function which provides this functionality?
I don't want to make any sort of copy of the list nor modify the list.
It would be enough if I could get at least a reverse iterator on a list in this case though.
Also, I know how to implement this myself. I'm just asking if Java already provides something like this.
Demo implementation:
static <T> Iterable<T> iterableReverseList(final List<T> l) {
return new Iterable<T>() {
public Iterator<T> iterator() {
return new Iterator<T>() {
ListIterator<T> listIter = l.listIterator(l.size());
public boolean hasNext() { return listIter.hasPrevious(); }
public T next() { return listIter.previous(); }
public void remove() { listIter.remove(); }
};
}
};
}
I just have found out that some List implementations have descendingIterator() which is what I need. Though there is no general such implementation for List. Which is kind of strange because the implementation I have seen in LinkedList is general enough to work with any List.
Use the .clone() method on your List. It will return a shallow copy, meaning that it will contain pointers to the same objects, so you won't have to copy the list. Then just use Collections.
Ergo,
Collections.reverse(list.clone());
If you are using a List and don't have access to clone() you can use subList():
List<?> shallowCopy = list.subList(0, list.size());
Collections.reverse(shallowCopy);
Guava provides this: Lists.reverse(List)
List<String> letters = ImmutableList.of("a", "b", "c");
List<String> reverseView = Lists.reverse(letters);
System.out.println(reverseView); // [c, b, a]
Unlike Collections.reverse, this is purely a view... it doesn't alter the ordering of elements in the original list. Additionally, with an original list that is modifiable, changes to both the original list and the view are reflected in the other.
If i have understood correct then it is one line of code .It worked for me .
Collections.reverse(yourList);
Its not exactly elegant, but if you use List.listIterator(int index) you can get a bi-directional ListIterator to the end of the list:
//Assume List<String> foo;
ListIterator li = foo.listIterator(foo.size());
while (li.hasPrevious()) {
String curr = li.previous();
}
I use this:
public class ReversedView<E> extends AbstractList<E>{
public static <E> List<E> of(List<E> list) {
return new ReversedView<>(list);
}
private final List<E> backingList;
private ReversedView(List<E> backingList){
this.backingList = backingList;
}
#Override
public E get(int i) {
return backingList.get(backingList.size()-i-1);
}
#Override
public int size() {
return backingList.size();
}
}
like this:
ReversedView.of(backingList) // is a fully-fledged generic (but read-only) list
java.util.Deque has descendingIterator() - if your List is a Deque, you can use that.
Collections.reverse(nums) ... It actually reverse the order of the elements.
Below code should be much appreciated -
List<Integer> nums = new ArrayList<Integer>();
nums.add(61);
nums.add(42);
nums.add(83);
nums.add(94);
nums.add(15);
//Tosort the collections uncomment the below line
//Collections.sort(nums);
Collections.reverse(nums);
System.out.println(nums);
Output: 15,94,83,42,61
I know this is an old post but today I was looking for something like this. In the end I wrote the code myself:
private List reverseList(List myList) {
List invertedList = new ArrayList();
for (int i = myList.size() - 1; i >= 0; i--) {
invertedList.add(myList.get(i));
}
return invertedList;
}
Not recommended for long Lists, this is not optimized at all. It's kind of an easy solution for controlled scenarios (the Lists I handle have no more than 100 elements).
Hope it helps somebody.
You can also invert the position when you request an object:
Object obj = list.get(list.size() - 1 - position);
For small sized list we can create LinkedList and then can make use of descending iterator as:
List<String> stringList = new ArrayList<>(Arrays.asList("One", "Two", "Three"));
stringList.stream().collect(Collectors.toCollection(LinkedList::new))
.descendingIterator().
forEachRemaining(System.out::println); // Three, Two, One
System.out.println(stringList); // One, Two, Three
You can also do this:
static ArrayList<String> reverseReturn(ArrayList<String> alist)
{
if(alist==null || alist.isEmpty())
{
return null;
}
ArrayList<String> rlist = new ArrayList<>(alist);
Collections.reverse(rlist);
return rlist;
}

Iterating through a list in reverse order in java

I'm migrating a piece of code to make use of generics. One argument for doing so is that the for loop is much cleaner than keeping track of indexes, or using an explicit iterator.
In about half the cases, the list (an ArrayList) is being iterated in reverse order by using an index today.
Can someone suggest a cleaner way of doing this (since I dislike the indexed for loop when working with collections), though it does work?
for (int i = nodes.size() - 1; i >= 0; i--) {
final Node each = (Node) nodes.get(i);
...
}
Note: I can't add any new dependencies outside the JDK.
Try this:
// Substitute appropriate type.
ArrayList<...> a = new ArrayList<...>();
// Add elements to list.
// Generate an iterator. Start just after the last element.
ListIterator li = a.listIterator(a.size());
// Iterate in reverse.
while(li.hasPrevious()) {
System.out.println(li.previous());
}
Guava offers Lists#reverse(List) and ImmutableList#reverse(). As in most cases for Guava, the former delegates to the latter if the argument is an ImmutableList, so you can use the former in all cases. These do not create new copies of the list but just "reversed views" of it.
Example
List reversed = ImmutableList.copyOf(myList).reverse();
I don't think it's possible using the for loop syntax. The only thing I can suggest is to do something like:
Collections.reverse(list);
for (Object o : list) {
...
}
... but I wouldn't say this is "cleaner" given that it's going to be less efficient.
Option 1: Have you thought about reversing the List with Collections#reverse() and then using foreach?
Of course, you may also want to refactor your code such that the list is ordered correctly so you don't have to reverse it, which uses extra space/time.
EDIT:
Option 2: Alternatively, could you use a Deque instead of an ArrayList? It will allow you to iterate forwards and backwards
EDIT:
Option 3: As others have suggested, you could write an Iterator that will go through the list in reverse, here is an example:
import java.util.Iterator;
import java.util.List;
public class ReverseIterator<T> implements Iterator<T>, Iterable<T> {
private final List<T> list;
private int position;
public ReverseIterator(List<T> list) {
this.list = list;
this.position = list.size() - 1;
}
#Override
public Iterator<T> iterator() {
return this;
}
#Override
public boolean hasNext() {
return position >= 0;
}
#Override
public T next() {
return list.get(position--);
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
for (String s : new ReverseIterator<String>(list)) {
System.out.println(s);
}
You could use the concrete class LinkedList instead of the general interface List. Then you have a descendingIterator for iterating with the reverse direction.
LinkedList<String > linkedList;
for( Iterator<String > it = linkedList.descendingIterator(); it.hasNext(); ) {
String text = it.next();
}
Don't know why there is no descendingIterator with ArrayList...
This is an old question, but it's lacking a java8-friendly answer. Here are some ways of reverse-iterating the list, with the help of the Streaming API:
List<Integer> list = new ArrayList<Integer>(Arrays.asList(1, 3, 3, 7, 5));
list.stream().forEach(System.out::println); // 1 3 3 7 5
int size = list.size();
ListIterator<Integer> it = list.listIterator(size);
Stream.generate(it::previous).limit(size)
.forEach(System.out::println); // 5 7 3 3 1
ListIterator<Integer> it2 = list.listIterator(size);
Stream.iterate(it2.previous(), i -> it2.previous()).limit(size)
.forEach(System.out::println); // 5 7 3 3 1
// If list is RandomAccess (i.e. an ArrayList)
IntStream.range(0, size).map(i -> size - i - 1).map(list::get)
.forEach(System.out::println); // 5 7 3 3 1
// If list is RandomAccess (i.e. an ArrayList), less efficient due to sorting
IntStream.range(0, size).boxed().sorted(Comparator.reverseOrder())
.map(list::get).forEach(System.out::println); // 5 7 3 3 1
Here is an (untested) implementation of a ReverseIterable. When iterator() is called it creates and returns a private ReverseIterator implementation, which simply maps calls to hasNext() to hasPrevious() and calls to next() are mapped to previous(). It means you could iterate over an ArrayList in reverse as follows:
ArrayList<String> l = ...
for (String s : new ReverseIterable(l)) {
System.err.println(s);
}
Class Definition
public class ReverseIterable<T> implements Iterable<T> {
private static class ReverseIterator<T> implements Iterator {
private final ListIterator<T> it;
public boolean hasNext() {
return it.hasPrevious();
}
public T next() {
return it.previous();
}
public void remove() {
it.remove();
}
}
private final ArrayList<T> l;
public ReverseIterable(ArrayList<T> l) {
this.l = l;
}
public Iterator<T> iterator() {
return new ReverseIterator(l.listIterator(l.size()));
}
}
If the lists are fairly small so that performance is not a real issue, one can use the reverse-metod of the Lists-class in Google Guava. Yields pretty for-each-code, and the original list stays the same. Also, the reversed list is backed by the original list, so any change to the original list will be reflected in the reversed one.
import com.google.common.collect.Lists;
[...]
final List<String> myList = Lists.newArrayList("one", "two", "three");
final List<String> myReverseList = Lists.reverse(myList);
System.out.println(myList);
System.out.println(myReverseList);
myList.add("four");
System.out.println(myList);
System.out.println(myReverseList);
Yields the following result:
[one, two, three]
[three, two, one]
[one, two, three, four]
[four, three, two, one]
Which means that reverse iteration of myList can be written as:
for (final String someString : Lists.reverse(myList)) {
//do something
}
You could use ReverseListIterator from Apache Commons-Collections:
https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/iterators/ReverseListIterator.html
Very simple Example:
List<String> list = new ArrayList<String>();
list.add("ravi");
list.add("kant");
list.add("soni");
// Iterate to disply : result will be as --- ravi kant soni
for (String name : list) {
...
}
//Now call this method
Collections.reverse(list);
// iterate and print index wise : result will be as --- soni kant ravi
for (String name : list) {
...
}
To have code which looks like this:
List<Item> items;
...
for (Item item : In.reverse(items))
{
...
}
Put this code into a file called "In.java":
import java.util.*;
public enum In {;
public static final <T> Iterable<T> reverse(final List<T> list) {
return new ListReverseIterable<T>(list);
}
class ListReverseIterable<T> implements Iterable<T> {
private final List<T> mList;
public ListReverseIterable(final List<T> list) {
mList = list;
}
public Iterator<T> iterator() {
return new Iterator<T>() {
final ListIterator<T> it = mList.listIterator(mList.size());
public boolean hasNext() {
return it.hasPrevious();
}
public T next() {
return it.previous();
}
public void remove() {
it.remove();
}
};
}
}
}
Create a custom reverseIterable.
Also found google collections reverse method.
How about using DeQue:
var queue = new ArrayDeque<>(list);
while (!queue.isEmpty()) {
var first = reversed ? queue.removeLast() : queue.removeFirst();
var second = reversed ? queue.peekLast() : queue.peekFirst();
if (second != null) {
//your code goes here
}
}
As has been suggested at least twice, you can use descendingIterator with a Deque, in particular with a LinkedList. If you want to use the for-each loop (i.e., have an Iterable), you can construct and use a wraper like this:
import java.util.*;
public class Main {
public static class ReverseIterating<T> implements Iterable<T> {
private final LinkedList<T> list;
public ReverseIterating(LinkedList<T> list) {
this.list = list;
}
#Override
public Iterator<T> iterator() {
return list.descendingIterator();
}
}
public static void main(String... args) {
LinkedList<String> list = new LinkedList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
for (String s : new ReverseIterating<String>(list)) {
System.out.println(s);
}
}
}
Valid for Java 9+
List<String> strList = List.of("a", "b", "c", "d", "e");
IntStream.iterate(strList.size() - 1, i -> i >= 0, i -> --i)
.mapToObj(strList::get)
.forEach(System.out::println);
Reason : "Don't know why there is no descendingIterator with ArrayList..."
Since array list doesnot keep the list in the same order as data has been added to list. So, never use Arraylist .
Linked list will keep the data in same order of ADD to list.
So , above in my example, i used ArrayList() in order to make user to twist their mind and make them to workout something from their side.
Instead of this
List<String> list = new ArrayList<String>();
USE:
List<String> list = new LinkedList<String>();
list.add("ravi");
list.add("kant");
list.add("soni");
// Iterate to disply : result will be as --- ravi kant soni
for (String name : list) {
...
}
//Now call this method
Collections.reverse(list);
// iterate and print index wise : result will be as --- soni kant ravi
for (String name : list) {
...
}

Categories