Very rudimentary question but I have a loop e.g.
List<ObjectList> = //set of values inside.
for(Object data : ObjectList){
// how to access next element?
// current element is accesed by 'data'. I could get the index position and then increment but is there a easier way?
}
How would you get the next element/previous? I know there are iterators i can use and so on but i want to know a neat way to do it in a for loop.
You can but don't do it as the time complexity of the loop will
increase. Just use a normal loop with an int i looping variable.
If you still want to do it you can find the index this way:
int index = lst.indexOf(data);
Then index+1 is the index of the next element.
And index-1 is the index of the previous element.
Make two methods for next and pervious and pass list and element.
public static <T> T nextElement(List<T> list,T element){
int nextIndex=list.indexOf(element)+1;
return list.size()<nextIndexlist?null:list.get(nextIndex);
}
public static <T> T previousElement(List<T> list,T element){
int previousIndex=list.indexOf(element)-1;
return list.size()>previousIndexlist?null:list.get(previousIndex);
}
1)First way
for(ObjectList data : objectList){
ObjectList previousElement=previousElement(objectList,data);
ObjectList nextElement=nextElement(objectList,data);
}
2) Second way
for(int i=0;i<=objectList.size();i++){
ObjectList previousElement=objectList.size>i-1?null:objectList.get(i-1);
ObjectList nextElement=objectList.size<i+1?null:objectList.get(i+1);
}
3) Third way using iterator
Actually, your for-each isn't iterating a List. This,
List<ObjectList> = //set of values inside.
for(Object data : ObjectList){
}
Should look something like,
List<ObjectList> al = new ArrayList<>();
for(ObjectList data : al){ // <-- like so.
}
But that won't find any data until you populate the List.
Using a "normal" for-loop, this might be, what you are looking for:
List<Object> objectList = new ArrayList<>();
// add some data
for (int i = 0; i < objectList.size(); i++) {
System.out.println((i > 0) ? "previous Object: " + objectList.get(i - 1) : "No previous object, current is the first one.");
System.out.println("Current Object: " + objectList.get(i));
System.out.println((i < objectList.size()) ? "Next Object: " + objectList.get(i + 1) : "No next object, current is the last one.");
}
Key aspect is, that you have to use your loop variable (i in this case) to access your actual elements. i + 1 gives you the next element and i - 1 the previous.
I think what you is an iterator, its used like this:
List<ObjectList> list= //set of values inside.
Iterator<ObjectList> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
System.out.println(iterator.previous());
iterator.next()
}
It allows you to access the next and previous objects.
ListIterator:
There is the ListIterator which can a bit of stepping back and forth.
Mind in the code below previousIndex() yields -1 at the start.
for (ListIterator<Object> iter = objectList.listIterator(); iter.hasNext(); ) {
Object object = iter.next();
Object previous = objectList.get(iter.previousIndex()); // Might fail
Object next = objectList.get(iter.nextIndex()); // Might fail
if (iter.hasPrevious()) ... iter.previous();
}
I have a Hashtable<List<Integer>, List<Triples>> ResultIPM2 = new HashTable<>(), I want to work on the key part which is aList<Integer>contains three patterns {[2,3,4] , [3,2,4,3] , [2,4,3]}.What I want to do is, I want to remove [2,4,3] because it is a subset of [3,2,4,3]. How can I report just [2,4,3] and [3,2,4,3] .
Note that the intersection must be in the same order as the smaller list.
For example, if instead of [3,2,4,3] we had a pattern [3,2,3,4] we wouldn't remove any pattern. by "remove" I mean not showing the pattern when reporting it.Here is a piece of my code:
Please don't care about the other answers because I had to edit this old question in order to be able to ask a new question.Thank you
Set<List<Integer>> key = resultsIPM2.keySet();
boolean maximal = false;
for(List<Integer> p1 : key){
for(List<Integer> p2:key){
if(!p2.equals(p1)){
if(p1.containsAll(p2)){
System.out.println(p1);
}
}
}
}
You can't use the enhanced for loop to remove from the list. Use an explicit Iterator.
List<List<Pair>> newPattern = new CopyOnWriteArrayList<>();
//Algorithm : end of Line 14
Iterator<List<Pair> iter = ptList.iterator();
while(iter.hasNext()){
List<Pair> list = iter.next();
Iterator<Pair> pairIter = list.iterator();
while(pairIter.hasNext()){
Pair pair = pairIter.next();
if (getFrequency(pair) < minSupp){
pairIter.remove();
newPattern.add(list);
}
}
}
Iterator.remove() is the only safe way to modify a collection during iteration.
Use Iterator instead of the for-each construct when you need to remove the current element.
The for-each construct hides the iterator, so you cannot call remove. Therefore, the for-each construct is not usable for filtering.
Now regarding the code which you said dint work is because
Iterator <Pair> iter = pairList.iterator();
should be something like this
Iterator<List<Pair> iter = ptList.iterator();
then again when you do iter.next();
It will give you List<Pair> list not this Pair pair. So you need to iterate over the list again the compare and remove.
Eran gave you a very nice example follow that
You can not modify a List while you are in a foreach loop of this list. You can use a normal for-loop which just increments an int to get your element:
List<List<Pair>> newPattern = new CopyOnWriteArrayList<>();
//Algorithm : end of Line 14
for(int i = 0; i < ptList.size(); i++){
List<Pair> list = ptList.get(i);
for(int j = 0; j < list.size(); j++){
Pair pair = list.get(j);
if (getFrequency(pair) < minSupp){
list.remove(j);
j--;
newPattern.add(list);
}
}
}
What are the the best methods to get values that occur more than once in a large list of words without slowing my run time?. My file contains 1xx,xxx words and I put them into a linked list. Now, I want to get only the words that occur more than once out of that list.
For example, if a list contains:
....This is is is just a test test....
I want to get is and test and put them into another list using an iterator.
I don't know if my code is right, and I think that this is not the best solution to approach for this problem.
for(int i = 0; i < word.size(); i++) {
Word s = word.get(i);
Word s1 = word.get(i+1);
if(s.equals(s1)) {
newWord.add(s);
}
}
Put them all into HashSet instead of list and check the return value of add() method.
HashSet<Word> wordSet = new HashSet<>();
for(int i = 0; i < word.size(); i++) {
if(!wordSet.add(word.get(i)){
//Found duplicate
}
}
Note that you can also do it during/instead of creation of the list of the words.
Build a hashmap with the word as key and it count as value.
for(each word in list)
{
count = 1;
if(map.contains(word))
{
count = map.get(word);
}
else
count = 1;
map.put(word,count);
}
Then iterate over the hashmap and check if values is 1, and add the word to your list.
If you can sort the list, then finding duplicates is quick and easy.
Being somewhat new to the Java language I'm trying to familiarize myself with all the ways (or at least the non-pathological ones) that one might iterate through a list (or perhaps other collections) and the advantages or disadvantages of each.
Given a List<E> list object, I know of the following ways to loop through all elements:
Basic for loop (of course, there're equivalent while / do while loops as well)
// Not recommended (see below)!
for (int i = 0; i < list.size(); i++) {
E element = list.get(i);
// 1 - can call methods of element
// 2 - can use 'i' to make index-based calls to methods of list
// ...
}
Note: As #amarseillan pointed out, this form is a poor choice
for iterating over Lists, because the actual implementation of
the get method may not be as efficient as when using an Iterator.
For example, LinkedList implementations must traverse all of
the elements preceding i to get the i-th element.
In the above example there's no way for the List implementation to
"save its place" to make future iterations more efficient.
For an ArrayList it doesn't really matter, because the complexity/cost of get is constant time (O(1)) whereas for a LinkedList is it proportional to the size of the list (O(n)).
For more information about the computational complexity of the built-in Collections implementations, check out this question.
Enhanced for loop (nicely explained in this question)
for (E element : list) {
// 1 - can call methods of element
// ...
}
Iterator
for (Iterator<E> iter = list.iterator(); iter.hasNext(); ) {
E element = iter.next();
// 1 - can call methods of element
// 2 - can use iter.remove() to remove the current element from the list
// ...
}
ListIterator
for (ListIterator<E> iter = list.listIterator(); iter.hasNext(); ) {
E element = iter.next();
// 1 - can call methods of element
// 2 - can use iter.remove() to remove the current element from the list
// 3 - can use iter.add(...) to insert a new element into the list
// between element and iter->next()
// 4 - can use iter.set(...) to replace the current element
// ...
}
Functional Java
list.stream().map(e -> e + 1); // Can apply a transformation function for e
Iterable.forEach, Stream.forEach, ...
(A map method from Java 8's Stream API (see #i_am_zero's answer).)
In Java 8 collection classes that implement Iterable (for example, all Lists) now have a forEach method, which can be used instead of the for loop statement demonstrated above. (Here is another question that provides a good comparison.)
Arrays.asList(1,2,3,4).forEach(System.out::println);
// 1 - can call methods of an element
// 2 - would need reference to containing object to remove an item
// (TODO: someone please confirm / deny this)
// 3 - functionally separates iteration from the action
// being performed with each item.
Arrays.asList(1,2,3,4).stream().forEach(System.out::println);
// Same capabilities as above plus potentially greater
// utilization of parallelism
// (caution: consequently, order of execution is not guaranteed,
// see [Stream.forEachOrdered][stream-foreach-ordered] for more
// information about this).
What other ways are there, if any?
(BTW, my interest does not stem at all from a desire to optimize performance; I just want to know what forms are available to me as a developer.)
The three forms of looping are nearly identical. The enhanced for loop:
for (E element : list) {
. . .
}
is, according to the Java Language Specification, identical in effect to the explicit use of an iterator with a traditional for loop. In the third case, you can only modify the list contents by removing the current element and, then, only if you do it through the remove method of the iterator itself. With index-based iteration, you are free to modify the list in any way. However, adding or removing elements that come before the current index risks having your loop skipping elements or processing the same element multiple times; you need to adjust the loop index properly when you make such changes.
In all cases, element is a reference to the actual list element. None of the iteration methods makes a copy of anything in the list. Changes to the internal state of element will always be seen in the internal state of the corresponding element on the list.
Essentially, there are only two ways to iterate over a list: by using an index or by using an iterator. The enhanced for loop is just a syntactic shortcut introduced in Java 5 to avoid the tedium of explicitly defining an iterator. For both styles, you can come up with essentially trivial variations using for, while or do while blocks, but they all boil down to the same thing (or, rather, two things).
EDIT: As #iX3 points out in a comment, you can use a ListIterator to set the current element of a list as you are iterating. You would need to use List#listIterator() instead of List#iterator() to initialize the loop variable (which, obviously, would have to be declared a ListIterator rather than an Iterator).
Example of each kind listed in the question:
ListIterationExample.java
import java.util.*;
public class ListIterationExample {
public static void main(String []args){
List<Integer> numbers = new ArrayList<Integer>();
// populates list with initial values
for (Integer i : Arrays.asList(0,1,2,3,4,5,6,7))
numbers.add(i);
printList(numbers); // 0,1,2,3,4,5,6,7
// replaces each element with twice its value
for (int index=0; index < numbers.size(); index++) {
numbers.set(index, numbers.get(index)*2);
}
printList(numbers); // 0,2,4,6,8,10,12,14
// does nothing because list is not being changed
for (Integer number : numbers) {
number++; // number = new Integer(number+1);
}
printList(numbers); // 0,2,4,6,8,10,12,14
// same as above -- just different syntax
for (Iterator<Integer> iter = numbers.iterator(); iter.hasNext(); ) {
Integer number = iter.next();
number++;
}
printList(numbers); // 0,2,4,6,8,10,12,14
// ListIterator<?> provides an "add" method to insert elements
// between the current element and the cursor
for (ListIterator<Integer> iter = numbers.listIterator(); iter.hasNext(); ) {
Integer number = iter.next();
iter.add(number+1); // insert a number right before this
}
printList(numbers); // 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
// Iterator<?> provides a "remove" method to delete elements
// between the current element and the cursor
for (Iterator<Integer> iter = numbers.iterator(); iter.hasNext(); ) {
Integer number = iter.next();
if (number % 2 == 0) // if number is even
iter.remove(); // remove it from the collection
}
printList(numbers); // 1,3,5,7,9,11,13,15
// ListIterator<?> provides a "set" method to replace elements
for (ListIterator<Integer> iter = numbers.listIterator(); iter.hasNext(); ) {
Integer number = iter.next();
iter.set(number/2); // divide each element by 2
}
printList(numbers); // 0,1,2,3,4,5,6,7
}
public static void printList(List<Integer> numbers) {
StringBuilder sb = new StringBuilder();
for (Integer number : numbers) {
sb.append(number);
sb.append(",");
}
sb.deleteCharAt(sb.length()-1); // remove trailing comma
System.out.println(sb.toString());
}
}
The basic loop is not recommended as you do not know the implementation of the list.
If that was a LinkedList, each call to
list.get(i)
would be iterating over the list, resulting in N^2 time complexity.
A JDK8-style iteration:
public class IterationDemo {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3);
list.stream().forEach(elem -> System.out.println("element " + elem));
}
}
In Java 8 we have multiple ways to iterate over collection classes.
Using Iterable forEach
The collections that implement Iterable (for example all lists) now have forEach method. We can use method-reference introduced in Java 8.
Arrays.asList(1,2,3,4).forEach(System.out::println);
Using Streams forEach and forEachOrdered
We can also iterate over a list using Stream as:
Arrays.asList(1,2,3,4).stream().forEach(System.out::println);
Arrays.asList(1,2,3,4).stream().forEachOrdered(System.out::println);
We should prefer forEachOrdered over forEach because the behaviour of forEach is explicitly nondeterministic where as the forEachOrdered performs an action for each element of this stream, in the encounter order of the stream if the stream has a defined encounter order. So forEach does not guarantee that the order would be kept.
The advantage with streams is that we can also make use of parallel streams wherever appropriate. If the objective is only to print the items irrespective of the order then we can use parallel stream as:
Arrays.asList(1,2,3,4).parallelStream().forEach(System.out::println);
I don't know what you consider pathological, but let me provide some alternatives you could have not seen before:
List<E> sl= list ;
while( ! sl.empty() ) {
E element= sl.get(0) ;
.....
sl= sl.subList(1,sl.size());
}
Or its recursive version:
void visit(List<E> list) {
if( list.isEmpty() ) return;
E element= list.get(0) ;
....
visit(list.subList(1,list.size()));
}
Also, a recursive version of the classical for(int i=0... :
void visit(List<E> list,int pos) {
if( pos >= list.size() ) return;
E element= list.get(pos) ;
....
visit(list,pos+1);
}
I mention them because you are "somewhat new to Java" and this could be interesting.
You can use forEach starting from Java 8:
List<String> nameList = new ArrayList<>(
Arrays.asList("USA", "USSR", "UK"));
nameList.forEach((v) -> System.out.println(v));
In java 8 you can use List.forEach() method with lambda expression to iterate over a list.
import java.util.ArrayList;
import java.util.List;
public class TestA {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("Apple");
list.add("Orange");
list.add("Banana");
list.forEach(
(name) -> {
System.out.println(name);
}
);
}
}
In Java 8 or above, you can iterate a Hashset using forEach() method.
import java.util.HashSet;
public class HashSetTest {
public static void main(String[] args) {
HashSet<String> hSet = new HashSet<String>();
// Adding elements into your HashSet usind add()
hSet.add("test1");
hSet.add("test2");
hSet.add("test3");
// Iterating over hash set items
hSet.forEach(x -> System.out.println(x));
// Or you can write shorter:
hSet.forEach(System.out::println);
}
}
For a backward search you should use the following:
for (ListIterator<SomeClass> iterator = list.listIterator(list.size()); iterator.hasPrevious();) {
SomeClass item = iterator.previous();
...
item.remove(); // For instance.
}
If you want to know a position, use iterator.previousIndex(). It also helps to write an inner loop that compares two positions in the list (iterators are not equal).
Right, many alternatives are listed. The easiest and cleanest would be just using the enhanced for statement as below. The Expression is of some type that is iterable.
for ( FormalParameter : Expression ) Statement
For example, to iterate through, List<String> ids, we can simply so,
for (String str : ids) {
// Do something
}
Above you'll find all differents ways to iterate over a LIST.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class test1 {
public static void main(String[] args) {
//******* Exercise 1 : Write a Java program to create a new array list, add some colors (string) and print out the collection.
List<String> colors = new ArrayList<String>();
colors.add("Black");
colors.add("Red");
colors.add("Green");
colors.add("Blue");
System.out.println(colors);
//******* Exercise 2 : Write a Java program to iterate through all elements in a array list.
System.out.println("//******* Exercise 2");
List<Integer> list2 = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
// iteration type 1 : using FOR loop
System.out.println("// iteration type 1");
for(Integer nb : list2) {
System.out.print(nb + ", ");
}
System.out.println("\n");
// iteration type 2 : using FOR loop
System.out.println("// iteration type 2");
for(int i=0; i < list2.size(); i++) {
System.out.print(list2.get(i) + ", ");
}System.out.println("\n");
// iteration type 3 : using Do-While loop
System.out.println("// iteration type 3");
int index21 = 0;
do {
System.out.print(list2.get(index21) + ", ");
index21++;
}while(index21<list2.size());
System.out.println("\n");
// iteration type 4 : using While loop
System.out.println("// iteration type 4");
int index22 = 0;
while(index22<list2.size()) {
System.out.print(list2.get(index22) + ", ");
index22++;
}
System.out.println("\n");
// iteration type 5 : using Iterable forEach loop
System.out.println("// iteration type 5");
list2.forEach(elt -> {
System.out.print(elt + ", ");
});
System.out.println("\n");
// iteration type 6 : using Iterator
System.out.println("// iteration type 6");
Iterator<Integer> listIterator = list2.iterator();
while(listIterator.hasNext()) {
System.out.print( listIterator.next() + ", ");
}
System.out.println("\n");
// iteration type 7 : using Iterator (From the beginning)
System.out.println("// iteration type 7");
ListIterator<Integer> listIterator21 = list2.listIterator(list2.size());
while(listIterator21.hasPrevious()) {
System.out.print( listIterator21.previous() + ", ");
}
System.out.println("\n");
// iteration type 8 : using Iterator (From the End)
System.out.println("// iteration type 8");
ListIterator<Integer> listIterator22 = list2.listIterator();
while(listIterator22.hasNext()) {
System.out.print( listIterator22.next() + ", ");
}
System.out.println("\n");
}
}
You could always switch out the first and third examples with a while loop and a little more code. This gives you the advantage of being able to use the do-while:
int i = 0;
do{
E element = list.get(i);
i++;
}
while (i < list.size());
Of course, this kind of thing might cause a NullPointerException if the list.size() returns 0, becuase it always gets executed at least once. This can be fixed by testing if element is null before using its attributes / methods tho. Still, it's a lot simpler and easier to use the for loop