setSize ArrayList, when will it come?

K

Knute Johnson

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.
 
J

Jan Burse

Knute said:
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
 
E

Eric Sosman

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.
 
J

Jan Burse

Eric said:
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
 
J

Joshua Cranmer

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.
 
J

Jan Burse

Joshua said:
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.
 
J

Jan Burse

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
 
A

Andreas Leitgeb

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.
 
J

Jan Burse

Patricia said:
On 8/8/2011 7:16 PM, Jan Burse wrote:
...
...

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
 
J

Jan Burse

Andreas said:
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
 
J

Jan Burse

Jan said:
Patricia said:
On 8/8/2011 7:16 PM, Jan Burse wrote:
...
...

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);
}
}
 
J

Joshua Cranmer

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.
 
J

Jan Burse

Joshua said:
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.
 
R

Roedy Green

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.
 
J

Joshua Cranmer

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.
 
T

Tom Anderson

On 8/9/2011 9:58 AM, Roedy Green wrote:
...
...

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
 
J

Jan Burse

Joshua said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top