Create List<T> instance from Iterator<T> - java

Anyone know if there is a standard way to create a List from an Iterator instance?

I tend towards Guava's Lists.newArrayList(Iterator) because I generally have Guava as a dependency, and it already exists.

Use the Iterator to get every element and add it to a List.
List<String> list = new LinkedList<String>();
while(iter.hasNext()) { // iter is of type Iterator<String>
list.add(iter.next());
}

I had this need, and as a user of Apache Commons, this is what I did:
IteratorUtils.toList(iterator);
Javadoc here: https://commons.apache.org/proper/commons-collections/javadocs/api-3.2.2/org/apache/commons/collections/IteratorUtils.html#toList(java.util.Iterator)

In Java 8 you can use these ways (while verbose enough):
Iterator<String> iterator = ...;
List<String> list = StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED), false)
.collect(Collectors.toList());
or
Iterator<String> iterator = ...;
List<String> list = new ArrayList<>(); // or LinkedList() if more relevant (adding being faster for LinkedList)
iterator.forEachRemaining(list::add);

try something like the following:
public T List<T> listFromIterator(Iterator<T> iterator) {
List<T> result = new LinkedList<T>();
while(iterator.hasNext()) {
result.add(iterator.next());
}
}
One thing to note is that if the iterator is not at the beginning of your structure, you have no way of retrieving previous elements.
If you have the collection that the iterator is from, you can create a list by using a constructor that takes a collection. ex: the LinkedList constructor:
LinkedList(Collection<? extends E> c)

This is the way that I convert from List to Iterator and vice versa.
ArrayList arrayList = new ArrayList();
// add elements to the array list
arrayList.add("C");
arrayList.add("A");
arrayList.add("E");
arrayList.add("B");
arrayList.add("D");
arrayList.add("F");
// use iterator to display contents of arrayList
System.out.print("Original contents of arrayList: ");
Iterator iterator = arrayList.iterator();
ArrayList arrayList2 = new ArrayList();
while(iterator.hasNext()) {
Object element = iterator.next();
arrayList2.add(element);
System.out.print(element + " ");
}

Related

Is there a way to filter out the elements of a List containing object having a String element based on another List of String

I have a List of an object List<Object> which Objects contains String elements . Now There is also another List of String List<String> .
I want the first List to only contain objects which are elements of the second list.
What is the most efficient way to do this?
You can use the contains() method of the list and that's convenient in your case since it will equals() check the Strings.
e.g.
List<String> otherList = new ArrayList<>();
List<Object> test = new ArrayList<>();
Iterator<Object> it = test.iterator();
while(it.hasNext()){
if(!otherList.contains(it.next().getString())) it.remove();
}
or in Java8 streams
test.stream().filter(e -> otherList.contains(e.getString()))
.collect(Collectors.toList());
This will generate you a new List.

Removing item from list while iterating

While iterating through a list, an item can possibly be removed.
private void removeMethod(Object remObj){
Iterator<?> it = list.iterator();
while (it.hasNext()) {
Object curObj= it.next();
if (curObj == remObj) {
it.remove();
break;
}
}
}
The problem for me occurs when the above code can take place in another loop, which is actively iterating the original list.
private void performChecks(){
for(Object obj : list){
//perform series of checks, which could result in removeMethod
//being called on a different object in the list, not the current one
}
}
How can I remove an unknown object from a list while traversing it?
Example
I have a list of listener objects. While notifying the listeners of an event, other listeners may no longer be needed.
If I understand your problem correctly, followings would be the possible solutions(might not be most effective but i think is worth a shot):
Under performChecks() use for(Object obj : list.toArray())
Advantage: every time the list is "refreshed" to array it will reflect the changes.
Therefore, if the item is removed from the list in the separate loop
Your question is a bit confusing so I'll answer what I think I understand; your question comes to this: how to remove an item from a list while the list is iterated concurrently and items are being removed OR how to avoid ConcurrentModificationException.
First, the problem in your code is that you remove the item with your iterator and not by the list. Second, if you're using concurrency, use the CopyOnWriteArrayList and remove the item with
list.remove()
to provide a good example for the scenario, check this
so this is not good:
List<String> myList = new ArrayList<String>();
myList.add("1");
myList.add("2");
myList.add("3");
myList.add("4");
myList.add("5");
Iterator<String> it = myList.iterator();
while(it.hasNext()){
String value = it.next();
System.out.println("List Value:"+value);
if(value.equals("3")) myList.remove(value);
}
and this is good:
List<String> myList = new CopyOnWriteArrayList<String>();
myList.add("1");
myList.add("2");
myList.add("3");
myList.add("4");
myList.add("5");
Iterator<String> it = myList.iterator();
while(it.hasNext()){
String value = it.next();
System.out.println("List Value:"+value);
if(value.equals("3")){
myList.remove("4");
myList.add("6");
myList.add("7");
}
}
System.out.println("List Size:"+myList.size());

Java get last element of a collection

I have a collection, I want to get the last element of the collection. What's the most straighforward and fast way to do so?
One solution is to first toArray(), and then return the last element of the array. Is there any other better ones?
A Collection is not a necessarily ordered set of elements so there may not be a concept of the "last" element. If you want something that's ordered, you can use a SortedSet/NavigableSet which has a last() method. Or you can use a List and call mylist.get(mylist.size()-1);
If you really need the last element you should use a List or a SortedSet/NavigableSet. But if all you have is a Collection and you really, really, really need the last element, you could use toArray() or you could use an Iterator and iterate to the end of the list.
For example:
public Object getLastElement(final Collection c) {
final Iterator itr = c.iterator();
Object lastElement = itr.next();
while(itr.hasNext()) {
lastElement = itr.next();
}
return lastElement;
}
Iterables.getLast from Google Guava.
It has some optimization for Lists and SortedSets too.
It is not very efficient solution, but working one:
public static <T> T getFirstElement(final Iterable<T> elements) {
return elements.iterator().next();
}
public static <T> T getLastElement(final Iterable<T> elements) {
T lastElement = null;
for (T element : elements) {
lastElement = element;
}
return lastElement;
}
This should work without converting to List/Array:
collectionName.stream().reduce((prev, next) -> next).orElse(null)
Well one solution could be:
list.get(list.size()-1)
Edit: You have to convert the collection to a list before maybe like this: new ArrayList(coll)
A reasonable solution would be to use an iterator if you don't know anything about the underlying Collection, but do know that there is a "last" element. This isn't always the case, not all Collections are ordered.
Object lastElement = null;
for (Iterator collectionItr = c.iterator(); collectionItr.hasNext(); ) {
lastElement = collectionItr.next();
}
There isn't a last() or first() method in a Collection interface. For getting the last method, you can either do get(size() - 1) on a List or reverse the List and do get(0). I don't see a need to have last() method in any Collection API unless you are dealing with Stacks or Queues
Or you can use a for-each loop:
Collection<X> items = ...;
X last = null;
for (X x : items) last = x;
If you have Iterable convert to stream and find last element
Iterator<String> sourceIterator = Arrays.asList("one", "two", "three").iterator();
Iterable<String> iterable = () -> sourceIterator;
String last = StreamSupport.stream(iterable.spliterator(), false).reduce((first, second) -> second).orElse(null);

in java,how to iterate list of objects

i am having the list myEmpls
List myEmpls = new ArrayList();
In this list i have added used defined objects.
LogConf e = getLogs(el);
//add it to list
myEmpls.add(e);
Now how to iterate the list of objects and get the values from this objects.
How to do this?
You could just google this and you would find tons of solutions.. But here is the code:
for(LogConf element : myEmpls) {
System.out.println(element.getValue());
}
You should also get used to define the type of the elements in the list:
List<LogConf> myEmpls = new ArrayList<LogConf>();
I know its been some time since this post was made. You can also use the Iterator.
List myEmpls = new ArrayList();
Iterator itr = myEmpls.iterator();
while(itr.hasNext()) {
LogConf Logobj = (LogConf) itr.next();
System.out.println(Logobj.getterName());
}
Hope this helps someone.

how to init an iterator

i just intent to initialize an iterator over a generic linked list like that (generic typ T seems to be erased in here since the site interpret it as tag)
public <T> LinkedList<T> sort(LinkedList<T> list){
Iterator<T> iter = new list.iterator();
...
but i got the error:
"list cannot be resolved"
what's wrong?
Remove the new keyword:
Iterator<T> iter = list.iterator();
To further clarify Mykola's correct answer: you're trying to create a new object of the class list. So you just want to call list.iterator() (which, somewhere inside it, is itself doing new Iterator or something like it and returning that to you).
Since you're clearly using Java 5 or above, though, the better way might be instead of doing
public <T> LinkedList<T> sort(LinkedList<T> list){
Iterator<T> iter = new list.iterator();
while (iter.hasNext()){
T t = iter.next();
...
}
}
instead doing this:
public <T> LinkedList<T> sort(LinkedList<T> list){
for (T t : list){
...
}
}
Still better, don't write that method at all and instead use
Collections.sort(list);
The word followed by new operator must be a Class name. Here list.iterator() is already returning a Object. So at this point new is uncessary.

Categories