Lets talk Arraylists/Hashmaps... (Discussion)

Discussion in 'Plugin Development' started by Orcem12, Oct 3, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    Orcem12

    We've all either used Hashmaps and/or Arraylists. So lets have a discussion on how and when to use them and how to use them appropriately. I've used Arraylists in the past and quite a few of them. Around 4 for one plugin. Is this a bad thing or does it really make a difference?

    If using a substantial amount Arraylists/Hashmpas is a bad thing, how else would you go about storing data internally?

    Thanks in advance for all intellectual feedback. Just trying to learn how to code better.
     
  2. Offline

    Loogeh

    Not sure if it's bad but i use 10 - 20 arraylists for cooldowns on abilities.
     
  3. Offline

    Orcem12

    Hm, interesting. I'd like to hear if and why it's would be bad and good. Simply because I'm interested to see how others handle large amounts of data. I mean everything can get stored to YAML's but is there a cutoff point for internal storage?
     
  4. Offline

    makskay

    I generally decide what data type to use solely based on how I'm going to want to access the data. I use ArrayLists for situations in which the order of item addition matters, HashMaps for situations in which I want to easily be able to "look up" some extra data attached to another object (like a playername mapping to a PlayerData object with stuff that the plugin needs to know about each "registered" player), and HashSets for situations in which I just need a simple "pile" into which I can toss objects (i.e. when the only thing I need to know about them is whether they're in the collection or not.)

    There's nothing particularly "wrong" with using a bunch of collections; they are, after all, designed to be the most efficient way to store data in an organized fashion. If you're experiencing performance issues with collection usage, it can help to create them with appropriate initial capacities and load factors that optimize their memory usage and frequency of size refactorization.
     
  5. Offline

    Orcem12

    @makskay
    Excellent, thanks for taking the time to explain everything. Really detailed as well. So I noticed that you like to be very diverse when it comes to using certain objects and storing data. I might start practicing this style as well. Thanks for the insight.

    Now say I'm using 5 ArrayLists. How would manage them in the most efficient way possible? As you said "optimize memory usage"? If there is, in fact, a way.
     
  6. Offline

    Orcem12

  7. Offline

    makskay

    I don't think he's upset, just posting some useful resources regarding how each collection type is best used - essentially a more in-depth version of my brief Set/List/Map explanation above :)
     
  8. Offline

    Orcem12

    I have a bad time when reading the internet then, haha. And if that's the case then that's awesome. The more knowledge we can spread the better.
     
  9. Yeah, not upset, just that "oh look, it's that thread again" feeling ;)
    With the difference that it's actually a really important and teaching topic in this case, so I don't have a problem with it popping up every now and then. Just providing some existing information for reference :)

    Most people just use ArrayLists all the time without thinking about better alternatives.
    For example the problem "on x, add player to collection; on y, check if player is in that collection and do something".
    A perfect scenario to use HashSets over a List, but many people don't even know about them.
     
  10. Offline

    Orcem12

    Would you mind providing a link or example of using a HashSet? For myself and other developers and future developers.
     
  11. Offline

    Sagacious_Zed Bukkit Docs

  12. Offline

    andf54

    Unless you don’t code a complete mess, then there is no general way of optimizing memory.
    It totally depends on what you do with the lists.

    If you want advice on using Lists, then drop your code somewhere (assuming it's not very long) and let more experienced coders criticise it.
     
  13. HashSet, quick summary:
    • use when your primary objective is to see whether or not something is there
    • does not allow duplicate entries (which is often helpful)
    • does not order entries - iteration* order is not consistent (a LinkedHashSet does this)
    • does not sort entries (a TreeSet does)
    • is rather quick at adding/removing elements anywhere
    • isn't as quick at iteration* as a List, but not extremely slow as well
    Example use:
    - We have players A, B and C who are having some feature enabled

    Code:
    // for your class
    private Set<String> enabledPlayers = new HashSet<String>();
     
    // in your event/command where people are added to that set:
    enabledPlayers.add(player.getName());
     
    // in your event/command where people are removed from that set:
    enabledPlayers.remove(player.getName());
     
    // in your event/whatever where something happens for the enabled players
    if (enabledPlayers.contains(player.getName()) {
        // do something with playerName
    }
     
    // if you need to something with everyone in that set
    for (String playerName : enabledPlayers) {
        // do something with playerName
    }

    What classes can be used:
    In the example, I used "String" as the type argument* for the HashSet (representing the players' names).
    When using more complex (non-primitive) classes, it is important that these classes override the methods hashCode() and equals() appropiately, so the HashSet can take advantage of what it was made for: hashing.
    (the same rule applies to keys of a HashMap, by the way)

    Hashing is a really complicated concept. Here's a pretty good guide to it, if you are interested. For simple Sets (using Strings or even primitive types*), you generally don't need to worry about it.

    Set Alternatives:
    • LinkedHashSet - same as HashSet, but iteration happens in insertion order; internally uses an additional LinkedList to store stuff, so it has higher RAM usage
    • TreeSet - additionally sorts elements based on a Comparator or natural ordering (numerical, alpha-numerical)
    • EnumSet - a Set of certain elements of an enumerator. Optimized to work with the special advantages that are there with enums. Could be used for example with bukkit Materials. Note that you can't construct them, but you have to use its factory methods. Google is your friend! (Note: There's also an EnumMap, same concept)
    *Definition of terms used in this post:
    • iteration - Looping over all elements contained in a collection. Usually done with a for-loop, in HashSets more commonly with an Iterator (or a foreach-loop aka enhanced for-loop)
    • type argument - based on Java's so-called "generics", that's the class you write between the "<>" brackets.
    • primitive types - The basic numerical classes that Java offers (all starting lower-case): boolean, byte, char, int, float, long, double
    Someone please correct me if I remembered something incorrectly in the summary.
    Oh, and this turned out way longer than I thought it would - once again :D
     
    devilquak likes this.
  14. Offline

    Orcem12

    Very awesome. Saving this bad boy to a word doc, haha. Thanks for taking your time to carefully explain it! It's greatly appreciated. Thanks again!
    Sounds great! I'll find one of my older projects or just make it the way I would and present it to everyone.
     
Thread Status:
Not open for further replies.

Share This Page