My implementation is similar to Bear's (excluding items):
Each area has a list of Actors (base class for Monster and Player), that is only iterated through if I need to find monsters within FOV (for ranged targeting) or other such effects.
For collision, I have each map Tile point to its Actor, null if none (only one Actor per tile). Similar to Hajo's approach, since the tiles are stored in a 2D array by coordinate, this allows for quick collision checks (passable = tile.isPassable && tile.actor == null) and the ability to draw a map by iterating through tiles and not having to iterate through any external monster/item list.
The downside to this approach is, of course, that when an Actor moves (Actors keep track of their x and y), it must notify the map so that the reference can be removed from the previous tile and placed on the new one. Minor, considering the benefits.
Hope this helps!
Ebyan "Nolithius" Alvarez-Buylla
http://www.nolithius.com