Best way to iterate through ArrayList?

I’ve kind of wondered about that ever since I started doing Java a couple of years ago and looked through people’s code. I’d noticed LinkedLists weren’t really used but never really thought about why. This post made me look into it and now I know it’s because array processing is more cache friendly! Well I’ll be… ::slight_smile: Guess I’m a bit behind the cutting edge here. The C++ code I’ve seen and worked on over the years uses plenty of linked lists, but I guess was mostly written before cache architectures became common.

Anyway I took a look at the only place I’ve used a LinkedList in my Java code so far (as the A* open list) and swapped it out for an ArrayList just for kicks. Who knew, the ArrayList is straight away quicker a lot of the time, even though the code was specifically written to work with a LinkedList!!! Haha, what a waste of time those data structure courses were :smiley:

Having said that, the linked list comes back into its own with a less aggressive heuristic function, and if I put more obstacles in the way, because it gets costly to insert all the new nodes into the array. So now I have to decide if I can be bothered to rewrite or not - if I do I’ll probably home bake something in between using some of the suggestions people have made in this thread.

Either way it’s been a good learning day :slight_smile:

For me it’s either regular Array[], ArrayList or ArrayDeque: :persecutioncomplex:
http://docs.oracle.com/javase/8/docs/api/java/util/ArrayDeque.html

What about: for (Enemy e : getEnemies()) enemies.add(e); :stuck_out_tongue:
or even 133t: enemies.addAll( java.util.Arrays.asList(getEnemies()) );

That is what I’m currently using… But what is the best way to make ‘getEnemies’?

It’s not what you’re currently using, because it throws a ConcurrentModificationException.

What do you mean how to make getEnemies()? Why are you using an array in the first place?

I find that the simple technique like this:


for(int i = 0; i < array.size(); i++) {
     System.out.println(i);
}

Works best. I have tried to iterate through array lists using an advanced for loop and I mean it works, but it seems to not like Slick2D and other libraries i use so I have gotten errors many a time.

If you wanted to get as close as you can to an advance for loop and iterate though objects in the for loop you could do this:


ArrayList<Player> list = new ArrayList<Player>();

Player tempPlayer;

for(int i = 0; i < list.size(); i++) {
     tempPlayer = list.get(i);

     //This line is just to show a use. Not necessary.
     System.out.println("X: " + tempPlayer.x, "Y: " + tempPlayer.y);
}

Good luck with your games, man!

I like Streams too, so if you use Java 8 you can use them!


// One Operation
array.stream().forEach(val -> val.doSomething());

// Multiple Operations:
array.stream().forEach(val -> {
    val.doSomething();
    val.doSomeOtherThings();
});

// You could even make crazy things like this:
array.stream().filter(val -> val.isAThing())
              .forEach(thing -> thing.doSomething());

Just wanted to show some examples for this :wink:
For some more methods you can look into the Java Doc.

If you think that’s crazy…

Didn’t want to make it too complicated :smiley:

@Jacob_Pickens: That method will cause silent problems if you remove entities during iteration.

In my CS class we wrote a collection that implements set operations (union, difference, etc.), and to prove a point to one of my classmates I wrote mine so that each method had only one statement, so here’s the intersection of sets:


return list.stream().distinct()
    .flatMap(t -> generate(() -> t).limit(min(getFrequencyOf(t), other.getFrequencyOf(t))))
    .collect(() -> new ArrayListBagExtension<>(type), (c, e) -> c.add(e), (c1, c2) -> c1.list.addAll(c2.list));

getFrequencyOf is a bit more sane: [icode]return (int) list.stream().filter(e -> anEntry.equals(e)).count();[/icode]

Don’t try this at home kids!

It’s for my game engine… I’m using usual arrays from get methods for simplicity and security…

Ask yourself if using arrays is really simpler and more secure and why.

I wouldn’t convert back and forth between arrays and lists all the time, but just go with List everywhere in the API (except for primitive types) .

If you insist on converting lists to arrays, use [icode]list.toArray(new Type[list.size()])[/icode] to avoid unnecessary allocations (see toArray javadoc)

Compare this:


for (int i = 0; i < things.size(); i++) {
    Thing thing = things.get(i);

    // Do Something.
}

To this:


for (Thing thing : things) {
    // Do Something.
}

Huge difference, much faster to do IMO.

  • Jev

Looks faster only because it’s “smaller”… but it does a lot of things under the hood that you might not need or want it to do and stops you doing a bunch of things that you might want it to do. Know thy requirements! The question for the whole topic title is loaded.

Cas :slight_smile:

I’m not switching between the two all the time… I’m just converting from ArrayList to arrays when the programmer wants it…

Before I was using ‘array.toArray(new [0]);’ but I just found out by looking at the code that it will create a new array if I do that…

Best way to iterate through ArrayList?

Once.

You should only convert an ArrayList to an array when you know that you aren’t going to be adding anything more to it and the libraries/frameworks you’re working with require it for many of their functions IMO.

  • Jev

Also I forgot to say…
I use array.toArray(new [array.size()]); because it creates a copy of the array so if the array changes during the loop (which happens alot) then nothing bad will happen…

Have you already tested List’s backwards loop remove() at least once: ???

for ( int len = projectiles.size(), i = len; i-- != 0; )
  if (projectiles.get(i).removeCriteria()) {
    projectiles.set(i, projectiles.get(--len));
    projectiles.remove(len);
  }

No need to have any extra array copy or whatever! :stuck_out_tongue: