setSize ArrayList, when will it come?

Discussion in 'Java' started by Jan Burse, Aug 8, 2011.

  1. Jan Burse

    Jan Burse Guest

    Jan Burse, Aug 8, 2011
    #1
    1. Advertising

  2. On 8/8/2011 3:47 PM, Jan Burse wrote:
    > Dear All
    >
    > When will ArrayList have a setSize() method. Its lack
    > makes it practically impossible to consistently replace
    > Vector by ArrayList.
    >
    > Any reason for brainlessly closing
    > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4147188
    > by oracle or who ever?


    It's because they hate you. They don't want you to have that method so
    it will drive you crazy. It's never going to have that method. It's a
    conspiracy of the highest order. They could add that method if they
    wanted to, but they don't.

    You know, you're not really paranoid if they're actually out to get you.

    The sun's almost over the yard arm here, go someplace quiet, have a
    beer, and chill.

    --

    Knute Johnson
     
    Knute Johnson, Aug 9, 2011
    #2
    1. Advertising

  3. Jan Burse

    Jan Burse Guest

    Knute Johnson schrieb:
    > On 8/8/2011 3:47 PM, Jan Burse wrote:
    >> Dear All
    >>
    >> When will ArrayList have a setSize() method. Its lack
    >> makes it practically impossible to consistently replace
    >> Vector by ArrayList.
    >>
    >> Any reason for brainlessly closing
    >> http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4147188
    >> by oracle or who ever?

    >
    > It's because they hate you. They don't want you to have that method so
    > it will drive you crazy. It's never going to have that method. It's a
    > conspiracy of the highest order. They could add that method if they
    > wanted to, but they don't.
    >
    > You know, you're not really paranoid if they're actually out to get you.
    >
    > The sun's almost over the yard arm here, go someplace quiet, have a
    > beer, and chill.
    >


    Lets make a facebook page (+) for ArrayList.setSize(). And have the
    beer later when it is not raining any more in southern germany (*)
    and northern switzerland.

    (+)
    http://www.facebook.com/groups/202554153131264/

    (*)
    http://www.mittelbayerische.de/nach..._i/690749/regen_sommer_treibt_deutsche_i.html
     
    Jan Burse, Aug 9, 2011
    #3
  4. Jan Burse

    Arne Vajhøj Guest

    On 8/8/2011 6:47 PM, Jan Burse wrote:
    > When will ArrayList have a setSize() method. Its lack
    > makes it practically impossible to consistently replace
    > Vector by ArrayList.
    >
    > Any reason for brainlessly closing
    > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4147188
    > by oracle or who ever?


    That type of usage is not what ArrayList was intended for.

    Those that need that functionality should simply implement
    a few utility methods to do what they want.

    Arne
     
    Arne Vajhøj, Aug 9, 2011
    #4
  5. Jan Burse

    Eric Sosman Guest

    On 8/8/2011 6:47 PM, Jan Burse wrote:
    > Dear All
    >
    > When will ArrayList have a setSize() method. Its lack
    > makes it practically impossible to consistently replace
    > Vector by ArrayList.
    >
    > Any reason for brainlessly closing
    > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4147188
    > by oracle or who ever?


    The first sentence of the referenced bug reads

    The ArrayList class in the new collections
    framework is not useful (in the way that the
    Vector class is) for implementing *sparse*,
    variable-size arrays.

    Part of this is true: ArrayList is not suitable for sparse
    arrays. The silent implication that Vector *is* suitable for
    sparse arrays, though, is false. Neither class is suitable
    for sparse arrays. (Demonstration: Try inserting [0]->"A"
    and [2173741823]->"Z" in either.)

    Perhaps if you'd explain your use case in more detail
    someone will have a suggestion you may find helpful.

    Also, it seems to me you should apologize to the responders
    and retract the word "brainlessly." More thought went into the
    response than into the complaint.

    --
    Eric Sosman
    d
     
    Eric Sosman, Aug 9, 2011
    #5
  6. Jan Burse

    Jan Burse Guest

    Eric Sosman schrieb:
    > Perhaps if you'd explain your use case in more detail
    > someone will have a suggestion you may find helpful.


    I have only referted to the meta use case in my post.
    The software refactoring use case, is replacing a synchronized
    Vector by an unsychronized ArrayList in regions where no synchronization
    is necessary.

    This meta use case could even have IDE support. For example
    IntelliJ has IDE support for the detection of unnessary
    use of StringBuffer and suggests the class StringBuilder.

    Similarly an IDE could suggest ArrayList in certain places
    where Vector is used. But it will not succeeded in such
    cases where I did use setSize on my Vector.

    I actually do use setSize for a kind of sparse Vector.
    Sparse in the sense that my Vector will have a couple
    of holes represented by null value elements. Which
    is eventually abuse of the term "sparse", but the use
    case is there.

    The missing thought in the reponse is the design goal
    of ArrayList. They are explicitly advertised in the
    class comment as unsynchronized version of Vector. It
    is brainless not to honor such a design goal in a response.

    On the other hand it is very clever to have the possibility
    of turning initial design goals into requests for
    enhancement. Imagine the following situation:

    You go into a restaurant and order pizza,
    you get your pizza without cheese, you
    ask the waiter what is wrong, and the waiter
    says, oh this cannot be changed, cheese has
    to be ordered separately.

    Brainless are we, who accept this.

    Best Regards
     
    Jan Burse, Aug 9, 2011
    #6
  7. On 8/8/2011 9:16 PM, Jan Burse wrote:
    > The missing thought in the reponse is the design goal
    > of ArrayList. They are explicitly advertised in the
    > class comment as unsynchronized version of Vector. It
    > is brainless not to honor such a design goal in a response.


    An unsynchronized version does not necessarily imply that it need be a
    full drop-in replacement for the class except with the synchronized
    methods removed. Now you're going to argue that it's brainless that

    Object a = new Vector();
    Object b = new ArrayList();
    System.out.println(a.getClass() == b.getClass());

    returns false.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
     
    Joshua Cranmer, Aug 9, 2011
    #7
  8. Jan Burse

    Jan Burse Guest

    Joshua Cranmer schrieb:
    >
    > returns false.


    And where is the drop-in manipulation, what was the before and after?
    I understand what you are heading for, the morning star is not
    evening star, yet they are the same.

    But typical scenario would be:

    Before:

    Object a = new Vector();
    Object b = new Vector();
    System.out.println(a.getClass() == b.getClass());

    returns true.

    After:

    Object a = new ArrayList();
    Object b = new ArrayList();
    System.out.println(a.getClass() == b.getClass());

    returns true.
     
    Jan Burse, Aug 9, 2011
    #8
  9. Jan Burse

    Jan Burse Guest

    But:

    Before:

    Vector a = new Vector();
    Vector b = new Vector();
    b.setSize(3);
    System.out.println(a.getClass() == b.getClass());

    returns true.

    After:

    (Since b makes use of setSize(). I can only
    replace a with an ArrayList)

    ArrayList a = new ArrayList ();
    Vector b = new Vector();
    b.setSize(3);
    System.out.println(a.getClass() == b.getClass());

    returns false;

    More than annoying, brainless.

    Best Regards

    Jan Burse schrieb:
    > Joshua Cranmer schrieb:
    >>
    >> returns false.

    >
    > And where is the drop-in manipulation, what was the before and after?
    > I understand what you are heading for, the morning star is not
    > evening star, yet they are the same.
    >
    > But typical scenario would be:
    >
    > Before:
    >
    > Object a = new Vector();
    > Object b = new Vector();
    > System.out.println(a.getClass() == b.getClass());
    >
    > returns true.
    >
    > After:
    >
    > Object a = new ArrayList();
    > Object b = new ArrayList();
    > System.out.println(a.getClass() == b.getClass());
    >
    > returns true.
    >
    >
     
    Jan Burse, Aug 9, 2011
    #9
  10. Joshua Cranmer <> wrote:
    > On 8/8/2011 9:16 PM, Jan Burse wrote:
    >> The missing thought in the reponse is the design goal
    >> of ArrayList. They are explicitly advertised in the
    >> class comment as unsynchronized version of Vector. It
    >> is brainless not to honor such a design goal in a response.


    > An unsynchronized version does not necessarily imply that it need be a
    > full drop-in replacement for the class except with the synchronized
    > methods removed.


    Whether "An unsynchronized version" implies "drop-in replacement
    except for the synchronisation" seems to be a bit fuzzy. To me
    it kind of does. But even if it didn't, then including a simple
    convenience method to simplify transition from Vector to ArrayList
    wouldn't appear as a mistake to me - even though there *is* a clumsy
    workaround for expanding and some different workaround for shrinking.

    > Now you're going to argue that it's brainless that ...


    Sorry to be so direct, but this "prognose" appeared entirely
    brainless to me. I know, that your arguments usually aren't.
    I guess this is just the type of answer you give to people
    that you "identified" as trolls.
     
    Andreas Leitgeb, Aug 9, 2011
    #10
  11. Jan Burse

    Jan Burse Guest

    Patricia Shanahan schrieb:
    > On 8/8/2011 7:16 PM, Jan Burse wrote:
    > ...
    >> I actually do use setSize for a kind of sparse Vector.
    >> Sparse in the sense that my Vector will have a couple
    >> of holes represented by null value elements. Which
    >> is eventually abuse of the term "sparse", but the use
    >> case is there.

    > ...
    >
    > If you only need small numbers of null elements, you could write a class
    > extending ArrayList that has setSize(). All you would do is loop adding
    > null elements or removing the tail elements until the ArrayList is the
    > required size.
    >
    > Patricia


    If only so many fields in ArrayList would not be private
    I could do that. But since for example in JDK 1.6.0_26
    none of the fields are protected, everything is private.

    What you suggest is theoretically sound but practically
    impossible. Look see:

    public class ArrayList<E> extends ...
    {
    private transient Object[] elementData;
    private int size;
    ...
    }

    And using reflection overriding this protection,
    is kind of ugly and eventually less performant.

    Bye
     
    Jan Burse, Aug 9, 2011
    #11
  12. Jan Burse

    Jan Burse Guest

    Andreas Leitgeb schrieb:
    > Sorry to be so direct, but this "prognose" appeared entirely
    > brainless to me. I know, that your arguments usually aren't.
    > I guess this is just the type of answer you give to people
    > that you "identified" as trolls.


    I guess you guys have nothing todo, except feeding each other
    in a troll like manner.

    Bye
     
    Jan Burse, Aug 9, 2011
    #12
  13. Jan Burse

    Jan Burse Guest

    Jan Burse schrieb:
    > Patricia Shanahan schrieb:
    >> On 8/8/2011 7:16 PM, Jan Burse wrote:
    >> ...
    >>> I actually do use setSize for a kind of sparse Vector.
    >>> Sparse in the sense that my Vector will have a couple
    >>> of holes represented by null value elements. Which
    >>> is eventually abuse of the term "sparse", but the use
    >>> case is there.

    >> ...
    >>
    >> If you only need small numbers of null elements, you could write a class
    >> extending ArrayList that has setSize(). All you would do is loop adding
    >> null elements or removing the tail elements until the ArrayList is the
    >> required size.
    >>
    >> Patricia

    >
    > If only so many fields in ArrayList would not be private
    > I could do that. But since for example in JDK 1.6.0_26
    > none of the fields are protected, everything is private.
    >
    > What you suggest is theoretically sound but practically
    > impossible. Look see:
    >
    > public class ArrayList<E> extends ...
    > {
    > private transient Object[] elementData;
    > private int size;
    > ...
    > }
    >
    > And using reflection overriding this protection,
    > is kind of ugly and eventually less performant.
    >
    > Bye


    Interestingly ArrayList has ensureCapacity() which
    is public. Whereby in Vector ensureCapacityHelper() is
    private.

    You are right, one could do a half way efficient setSize()
    with ensureCapacity() of ArrayList, by calling
    ensureCapacity() and then looping with add() of null.

    But the request and idea is to have an efficient setSize().
    In the spirit of the Vector setSize(). Namely:

    /* from vector */

    public synchronized void setSize(int newSize) {
    modCount++;
    if (newSize > elementCount) {
    ensureCapacityHelper(newSize);
    } else {
    for (int i = newSize ; i < elementCount ; i++) {
    elementData = null;
    }
    }
    elementCount = newSize;
    }

    The last statement and the preceeding loop are crucial.
    They require direct access to elementCount and elementData.
    These fields correspond to size and elementData in
    ArrayList.

    But maybe in some VMs/Plattforms/Architectur a loop add()
    after ensureCapacity() doesn't show any performance penalty
    and would be feasible. Have to check.

    Best Regards

    BTW: Both Vector and ArrayList have a little glitch, an
    unused variable, probably anyway optimized away by the
    JIT, but nevertheless:

    ArrayList:

    /* Glitch: oldData not used anymore. */

    public void ensureCapacity(int minCapacity) {
    modCount++;
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
    Object oldData[] = elementData;
    int newCapacity = (oldCapacity * 3)/2 + 1;
    if (newCapacity < minCapacity)
    newCapacity = minCapacity;
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
    }
    }

    Vector:

    /* Glitch: oldData not used anymore. */

    private void ensureCapacityHelper(int minCapacity) {
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
    Object[] oldData = elementData;
    int newCapacity = (capacityIncrement > 0) ?
    (oldCapacity + capacityIncrement) : (oldCapacity * 2);
    if (newCapacity < minCapacity) {
    newCapacity = minCapacity;
    }
    elementData = Arrays.copyOf(elementData, newCapacity);
    }
    }
     
    Jan Burse, Aug 9, 2011
    #13
  14. Jan Burse

    Jan Burse Guest

    Jan Burse schrieb:
    >
    > BTW: Both Vector and ArrayList have a little glitch, an
    > unused variable, probably anyway optimized away by the
    > JIT, but nevertheless:


    Ok, they saw that:
    http://bugs.sun.com/view_bug.do?bug_id=6812879
     
    Jan Burse, Aug 9, 2011
    #14
  15. On 8/9/2011 2:56 AM, Andreas Leitgeb wrote:
    > Joshua Cranmer<> wrote:
    >> Now you're going to argue that it's brainless that ...

    >
    > Sorry to be so direct, but this "prognose" appeared entirely
    > brainless to me. I know, that your arguments usually aren't.
    > I guess this is just the type of answer you give to people
    > that you "identified" as trolls.


    I meant it as a rhetorical device to show that the argument, applied
    strictly, leads to a rather untenable proposition. There are a fair
    number of observable differences between Vector and ArrayList, even if
    you exclude the part about synchronized methods.

    I would also like to point out that in the time you have spent arguing
    for this feature, you could have implemented a small class that had this
    feature already.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
     
    Joshua Cranmer, Aug 9, 2011
    #15
  16. Jan Burse

    Jan Burse Guest

    Joshua Cranmer schrieb:
    > There are a fair number of observable differences between Vector and
    > ArrayList, even if you exclude the part about synchronized methods.

    What are you refering to? Can you elaborate on your thoughts.
     
    Jan Burse, Aug 9, 2011
    #16
  17. Jan Burse

    Roedy Green Guest

    On Tue, 09 Aug 2011 00:47:12 +0200, Jan Burse <>
    wrote, quoted or indirectly quoted someone who said :

    >When will ArrayList have a setSize() method. Its lack
    >makes it practically impossible to consistently replace
    >Vector by ArrayList.


    This will not make you happy, but there is ArrayList.trimToSize

    To grow an ArrayList, you must do it one slot at a time.

    Further, I would hope ArrayList.addAll would be smart enough to grow
    the array only once, if needed.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com
    Most of computer code is for telling the computer
    what do if some very particular thing goes wrong.
     
    Roedy Green, Aug 9, 2011
    #17
  18. On 8/9/2011 11:30 AM, Jan Burse wrote:
    > Joshua Cranmer schrieb:
    >> There are a fair number of observable differences between Vector and
    >> ArrayList, even if you exclude the part about synchronized methods.

    > What are you refering to? Can you elaborate on your thoughts.


    Anything reflective is a dead giveaway, and I'm pretty sure that the two
    classes have slightly different sizes, so you could observe differences
    in memory characteristics.

    More seriously, the Collections API tweaked some method names
    differently, so there are a few methods in Vector which are kept around
    for legacy use (addElement, e.g.).

    In general, an ArrayList is a list that happens to be backed by an
    array. A Vector is a synchronized, automatically-growing array that
    leaks details about its array all over the place; it was shoehorned into
    the Collections API upon introduction to allow for a more gradual,
    correct migration.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
     
    Joshua Cranmer, Aug 9, 2011
    #18
  19. Jan Burse

    Tom Anderson Guest

    On Tue, 9 Aug 2011, Patricia Shanahan wrote:

    > On 8/9/2011 9:58 AM, Roedy Green wrote:
    > ...
    >> Further, I would hope ArrayList.addAll would be smart enough to grow
    >> the array only once, if needed.

    > ...
    >
    > It does the following:
    >
    > 1. Grow to the needed size.
    >
    > 2. Call the other collection's toArray method.
    >
    > 3. System.arraycopy the toArray result into the ArrayList's elementData.
    >
    > This double copy is going to be faster than the one at a time approach
    > only if large numbers of nulls are being added. If that is the case, the
    > structure is probably too sparse for ArrayList to be a good choice.


    It would be nice if ArrayList used a loop to do the copy for small added
    collections; it could cut over to the array method for larger addends.

    Anyway, with List.addAll and Collections.nCopies, we can write:

    <T> void setSize(List<T> list, int size) {
    int change = size - list.size();
    if (change > 0) {
    list.addAll(Collections.nCopies(change, null));
    }
    else if (change < 0) {
    list.subList(size, list.size()).clear();
    if (list instanceof ArrayList) ((ArrayList)list).trimToSize();
    }
    // else do nothing
    }

    I haven't tried that, but it should work.

    So, Jan, less whining, more coding, please.

    tom

    --
    As Emiliano Zapata supposedly said, "Better to die on your feet than
    live on your knees." And years after he died, Marlon Brando played him
    in a movie. So just think, if you unionize, Marlon Brando might play
    YOU in a movie. Even though he's dead. -- ChrisV82
     
    Tom Anderson, Aug 9, 2011
    #19
  20. Jan Burse

    Jan Burse Guest

    Joshua Cranmer schrieb:
    > Anything reflective is a dead giveaway, and I'm pretty sure that the two
    > classes have slightly different sizes, so you could observe differences
    > in memory characteristics.


    In vector you can parametrisize the growing characteristics, either
    by a constant increment or doubling the size. For this purpose there
    is an extra field not found in ArrayList.

    Array list always follows a 150% + 1 rule when growing the internal
    data buffer. There is no extra field need to store some parameter.
    But otherwise the two use the same data representation.

    But I think it would not prevent me from using ArrayList instead
    of Vector, that this parameter is missing. The 150% has its merits
    over the strategies implemented in vector.

    > More seriously, the Collections API tweaked some method names
    > differently, so there are a few methods in Vector which are kept
    > around for legacy use (addElement, e.g.).


    Yes when replacing Vector by ArrayList, one has to rename the method
    calls. For example instead of addElement() one needs to use add(), and
    instead of elementAt().

    But renaming methods does not prevent me from using ArrayList. As
    long each legacy method has a new buddy, I don't see any problem
    whatever with it.

    > In general, an ArrayList is a list that happens to be backed by an
    > array. A Vector is a synchronized, automatically-growing array that
    > leaks details about its array all over the place; it was shoehorned
    > into the Collections API upon introduction to allow for a more
    > gradual, correct migration.


    I don't see that Vector leaks more details than ArrayList about its
    implementation. Could you make an example? I only see that the fields
    of vector are protected, and well yes this means vector is not fully
    encapsulated.

    But I want to migrate to ArrayList whereever possible, so why should
    I bother that Vector is not fully encapsulated. And if ArrayList has
    the merrit that it is fully encapsulated the better.

    But the protected fields would only be seen by a subclass, which could
    sneak into some of your parameters of your methods, and spy on you or
    cheat on you. Since vector is not final. That is a drawback. But same
    problem with ArrayList.

    Vector and ArrayList both implement the following protocolls:
    AbstractList<E>
    List<E>,
    RandomAccess,
    Cloneable,
    Serializable

    If only somebody would have had the brains to include setSize()
    somewhere. List has the methods size(), add() and remove() in it.
    setSize(n) could be neatly abstractly specified as having the
    post condition size()=n and after.get(i)=before.get(i) for
    i<before.size() and after.get(i)=null for i>=before.size() and
    i<after.size().

    And the AbstractList could implement abstractly the inefficient
    setSize() that would use remove() and add(), when Random access is
    present via index, or otherwise maybe with a backward iterator.
    Backward iterator is also missing btw. And then concrete classes
    could provide more efficient implementations if necessary.

    Bye


    Best Regards
     
    Jan Burse, Aug 9, 2011
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Saravanan Rathinavelu

    Iterate through ArrayList using an another ArrayList

    Saravanan Rathinavelu, Aug 16, 2003, in forum: ASP .Net
    Replies:
    3
    Views:
    2,773
    Natty Gur
    Aug 19, 2003
  2. Douglas Masterson

    setSize problem

    Douglas Masterson, Sep 24, 2003, in forum: Java
    Replies:
    0
    Views:
    450
    Douglas Masterson
    Sep 24, 2003
  3. Kaidi
    Replies:
    4
    Views:
    2,439
    Kaidi
    Jan 3, 2004
  4. xz
    Replies:
    16
    Views:
    2,415
  5. Philipp
    Replies:
    6
    Views:
    943
    Arne Vajhøj
    May 28, 2008
Loading...

Share This Page