I have class which has an Iterator method ( public Iterator iterator(boolean fromFront) ) and my Iterator method returns a "new DoublyLinkedListIterator()". DoublyLinkedListIterator implements ListIterator which contains the set method. The problem is in my main where my iterator doesn't have access to the set method, Iterator iterator = deque.iterator(true); Nor do I have access to the hasPrevious or previous methods.
If you want to have access to the methods in DoublyLinkedListIterator, you have to return it instead of an Iterator. (Or make a cast before using it).
How to make a cast, in case you need it.
The standard way to expose a ListIterator is to have a public <T> ListIterator<T> listIterator() method on your class, as in the standard List class, so you can use it as:
ListIterator literator = deque.listIterator();
Note that the builtin Deque<T> class does not support ListIterators. The variable name is taken from your sample code, it has a custom type.
If you want to use iterator but want to navigate forward/backward and change the links order, ... to be short every write operation that modify the structure of the list, you're doing it wrong.
Go for the while/do-while loop if you have such needs.
Related
List < WebElement> LElement=driver.findElements(By.tagname("a"));
In the above case the driver.findElements will return the list of WebElement and Now we have the Object of List that is "LElement" ,Now suppose if i want to get the first Element i can use below code
LElement.get(0);
But my doubt here is the get() method is present in List interface So i should Create Object of Either ArrayList or LinkedList to implement this method..But in above case i can directly get result of get method without implementing from ArrayList or Linked List and directly from interface..Can somebody explain me about this?
This question is irrespective of selenium and is a concept called polymorphism in OOP.
The List interface provides abstract methods and the class implementing List should provide an implementation body for the abstract methods. Therefore the method get() in the List interface is implemented in the class ArrayList and the other implementations of the List interface. ArrayList is a type of List, therefore we can have something like this:
List<WebElement> webElements = new ArrayList<>();
Now let's say I want to create the API findElements for Selenium. If I create the method like this:
public ArrayList<WebElement> findElements(input..){
It would be tightly coupled with ArrayList and everyone will have to use ArrayList from their end to use that API's method, which is not desirable.
A better solution would be to use some abstract concept to represent the ArrayList, which turns out to be the List interface.
public List<WebElement> findElements(input..){
List<WebElements> webElements = new ArrayList<>();
webElements.addAll(some operations to populate the list)
return webElements;
}
This one is more flexible, how? Let's say after releasing the app, we deducted the implementation of ArrayList is not the best option for us to use for that use case, and we would like to use to LinkedList instead. Using the first way of writing the API, the consumers of the API would have to make the change from their side as well. Using the better way, they do not need to do anything :)
The List is still an instance of ArrayList; in the provided example. Selenium must have implemented something similar. We are getting a concrete implementation of List when we are invoking findElements, it is just that we do not know what implementation class we are getting but we do know that it provides implementation bodies for the abstract methods found in the List interface and we can use them.
I'm confused about the following situation related to Java OOP and Java API/source code arrangement. Based on Oracle's Java 8 API, hasNext() is an abstract method, but I couldn't find where hasNext() is implemented. I read that private inner classes are used to implement different Iterators in each Collection class, but there is no more info about how to find the location of the implementation. Some users suggested me to add Java JRE 1.8 source code to my Eclipse IDE, but I can only see boolean hasNext(); declared as an abstract method in the Iterator interface.
As the example shown below, the iterator obj uses hasNext() directly w/o implementing it. However, I was taught you need to implement an abstract method in an interface.
My Question:
(1) How do I find the implementation of the abstract method, hasNext()?
(2) A comment says I can find the code here. What's the reason to implement hasNext() in ArrayList class, but mark hasNext() as an abstract method? It is not intuitive to find the hasNext() implementation this way.
List<String> list = new ArrayList<String>();
list.add("item-1");
list.add("item-2");
list.add("item-3");
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
You can see in your code, that List is an ArrayList. The method in ArrayList called iterator() will return an implementation of Iterator. This implementation of Iterator will have the method hasNext() implemented.
It's great to be curious, and as the comment said, you can click into the code in an IDE (or if that doesn't work for you, set a break point in a debugger and step in). Reading the Java code is a great way to de-mystify it.
Of course, you can generally can expect the Java people to know what they are doing, and trust the implementations you get back to be sensible, and fit for general use. The caveat here is that you should also read the documentation. eg. from https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html
The iterators returned by this class's iterator and listIterator
methods are fail-fast: if the list is structurally modified at any
time after the iterator is created, in any way except through the
iterator's own remove or add methods, the iterator will throw a
ConcurrentModificationException. Thus, in the face of concurrent
modification, the iterator fails quickly and cleanly, rather than
risking arbitrary, non-deterministic behavior at an undetermined time
in the future.
An iterator over a collection. Iterator takes the place of Enumeration in the Java Collections Framework. Iterators differ from enumerations in two ways:
Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics.
Method names have been improved.
https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html
I was having the same question If ListIterator is interface which contains only abstract method which class is responsible for the implementation those methods.
arrived on the conclusion (correct me if I'm wrong)
ArrayList instance method ListIterator is returning instance of ListItr(0)
ListItr(java.util.ArrayList.ListItr) is the class which is implementing the ListIterator interface with the implementation of the abstract methods.
Technically ListIterator can hold instance of it's implementation class.
The next() and hasNext() methods are part of the Iterator interface. Each specific implementation will provide their own versions. You can take a look at how they are defined for the ArrayListIterator in the commons-collection library here or SingletonListIterator here.
I am providing a library for a different team. One of the methods I provide receives as argument an Iterator. I would like to somehow require a certain order of iteration. Is there any way to do this in code by extending Iterator?
Not directly. The iterator is made just to give you an item at time, avoiding to storing in memory and pass a whole list of values, which could be unfeasible at times.
Unless you have more knowledge on how the values are generated and which bounds have to be applied to the sorting of data, the only way is to get all elements from the iterator, store them in some list/vector/database, sort them and return another iterator using the sorted list.
You're being passed, as an argument, an instance of some concrete class which implements Iterator. You can't extend its class because its class is decided upon instantiation, which is done by the code that calls your method.
If you want to fail fast when the required order is not respected, try Guava's Ordering.isOrdered() method.
NB This will only work if your argument is an Iterable, rather than Iterator. You need it to be Iterable (an interface which allows you to retrieve the Iterator) so that you can iterate twice: once to check order, once to process.
Collection col = new LinkedList();
Is there a way to call col.addFirst ?
Yes, if you cast to LinkedList:
((LinkedList) col).addFirst(..)
But this is discouraged, because you don't always know the concrete type of the collection. You can check with instanceof, but that is not good object oriented code. If you really require a LinkedList, require a LinkedList (rather than Collection)
If you declare a variable as Collection, this means that you normally plan to consider this variable, in the rest of your program, as a simple Collection, and not as a linked list. The methods offered by the Collection interface should be sufficient for the rest of your program using this variable.
If you need access to a specific method only present in the LinkedList class, then the variable should be a declared as LinkedList.
I am not sure why you need to use Collection in this case, however you can still "program to an interface and not to an implementation" if you use the interface java.util.Deque which, by chance, also extends java.util.Collection
Deque<String> deque = new LinkedList<String>();
deque.addFirst("Hello");
Collection<String> collection = deque;
If you use List instead of Collection, then the .add() method is available. Add at index 0 to put it in on the first position.
list.add(0, object)
I am a beginner and I cannot understand the real effect of the Iterable interface.
Besides what Jeremy said, its main benefit is that it has its own bit of syntactic sugar: the enhanced for-loop. If you have, say, an Iterable<String>, you can do:
for (String str : myIterable) {
...
}
Nice and easy, isn't it? All the dirty work of creating the Iterator<String>, checking if it hasNext(), and calling str = getNext() is handled behind the scenes by the compiler.
And since most collections either implement Iterable or have a view that returns one (such as Map's keySet() or values()), this makes working with collections much easier.
The Iterable Javadoc gives a full list of classes that implement Iterable.
If you have a complicated data set, like a tree or a helical queue (yes, I just made that up), but you don't care how it's structured internally, you just want to get all elements one by one, you get it to return an iterator.
The complex object in question, be it a tree or a queue or a WombleBasket implements Iterable, and can return an iterator object that you can query using the Iterator methods.
That way, you can just ask it if it hasNext(), and if it does, you get the next() item, without worrying where to get it from the tree or wherever.
It returns an java.util.Iterator. It is mainly used to be able to use the implementing type in the enhanced for loop
List<Item> list = ...
for (Item i:list) {
// use i
}
Under the hood the compiler calls the list.iterator() and iterates it giving you the i inside the for loop.
An interface is at its heart a list of methods that a class should implement. The iterable interface is very simple -- there is only one method to implement: Iterator(). When a class implements the Iterable interface, it is telling other classes that you can get an Iterator object to use to iterate over (i.e., traverse) the data in the object.
Iterators basically allow for iteration over any Collection.
It's also what is required to use Java's for-each control statement.
The Iterable is defined as a generic type.
Iterable , where T type parameter represents the type of elements returned by the iterator.
An object that implements this interface allows it to be the target of the “foreach” statement. The for-each loop is used for iterating over arrays, collections.
read more -: https://examples.javacodegeeks.com/iterable-java-example-java-lang-iterable-interface/