what is the initial value of arrays of object

B

bbound

[lots of ideas deleted]

ArrayList literals. Maybe use [{item, item, item}] as the syntax (it
isn't currently legal with some different meaning, so no clash there).

Right now, we have the cumbersome

List<Foo> list = new ArrayList<Foo>();
Collections.addAll(list, item, item, item);

but, not to put too fine a point on it, that freaking blows.

List<Foo> list = [{item, item, item}];

is much nicer.

And before anyone says that it would be weird to add a literal for a
composite type, I'd like to remind everyone of the existence of String
literals, nevermind array literals. :)
 
A

Andreas Leitgeb

zerg said:
And what, exactly, is YOUR problem?

Indeed it was destructive: I wanted to *avoid* a re-incarnation of
the call-by-reference sore-topic to overwhelm the (in my mind)
interesting idea of creating arrays and populating them in one go.
 
P

Patricia Shanahan

Andreas said:
If you've devised some idiom for this kind of job, you effectively
agree to zerg, that there is indeed some use for that job. :)
....

I do have some cases in which I *might* want e.g. an array whose
elements are all initialized to different instances using a
parameterless constructor. I can't say I've actually needed it.

On the other hand, I have had situations in which I wanted an array
initialized according to some simple pattern, regardless of constructor
parameters, and picked the initialization block adjacent to the
declaration as my preferred solution.

Patricia
 
J

Joshua Cranmer

zerg said:
new prim[x](value) -> an array of the appropriate primitive type, each
cell assigned the specified value (e.g. new int[10](1) would produce an
array of ten ints with the value 1 instead of the normal 0; new int[10]
would still produce an array of ten zeros of course).

int[] randomArray = new int[x];
Arrays.fill(randomArray, 10);

I think that methodology looks and conveys the idea more clearly than a
|new int[x](10)| -- it almost feels like I'm making an array or
something of size 10.

Similarly, the syntax doesn't feel right, especially since
|new int[x](10)| and |new StringBuilder[x](10)| are using the same
syntax to do two different things: the first a shorthand in essence for
|foo = 10| and the latter for |new StringBuilder(10)|.
This sort of thing might not be used enough to justify the effort,
though, save perhaps for the not-infrequent case of initializing an
array of arrays with equal-sized subarrays (that is, making rectangular
two-dimensional arrays, or analogous structures in more dimensions).

|new int[10][5]| already works today; it seems you want to do that over
again?

Looking at my code, it seems that my most common array initializations
are of the following form:
* new int[0], or new int[] {a};
* list.toArray(new Object[0]);
* System.arraycopy
* An initialization requiring non-trivial computations per element or
other forms of performing for side effects.

I don't see a single instance where I need to invoke something like
for (int i=0; i < length; i++)
arr = new Foo();
 
J

Joshua Cranmer

Andreas said:
Zerg's proposal avoids verbose wording and yet keeps the full
initialisation together with the declaration and the constructor
(provided that indeed the thusly construed items are what is
wanted). It is far more concise than calling Array.fill for
primitives or looping for Objects.

I don't know, but I've always found the non-standard ways of
initialization rather... beautiful. For example, I have a Map initalized
as follows:
Map<String,String> map = new HashMap<String,PrimitiveClass>() {{
put("Key1", "Value1");
put("Key2", "Value2");
}};

Similarly with Lew's example of initializing a List.

The examples Patricia gave are much easier on my eyes, at least,
especially since the salient differences between null-initialization and
non-null initialization are more than a few characters.
PS: where I disagree to zerg is, that I'd actually *want* the
multiple-evaluation and making use of possible sideeffects:

List<String> list=getStringList(); // just for context
Iterator<String> it=list.iterator(); // just for context
MyObj moArr=new MyObj[list.size()](it.next());

I would agree that multiple-evaluation makes more sense as a use case,
BUT to do so would be to completely ignore Java's basic syntax style. So
multiple-evaluation is the ideal case but also a non-starter.
 
Z

zerg

Eric Sosman wrote:

(Eric Sosman calls me a liar, paranoid, and various other personal
attacks, but has nothing worthwhile to say, nor anything Java-related)


What terrible netiquette!
 
Z

zerg

Patricia said:
...

I do have some cases in which I *might* want e.g. an array whose
elements are all initialized to different instances using a
parameterless constructor. I can't say I've actually needed it.

Many many years ago: "I do have some cases in which I *might* want e.g.
a loop construct that counts from 1 to 100 using an integer. I can't say
I've actually needed it." -- Someone, during a debate as to whether to
add "for" loops to C, arguing that all anyone really needs is "while".

(REAL programmers prefer a conditionless while, and always write "while
(true) { ... if (something) break; ... }"!*)



:)



* A minority opinion holds that the CORRECT loop structure is actually
"for(;;) ... break". Another, "for (int i = 0; i < 1;)" with "i = 1" set
whenever it's determined that this should be the last iteration, and
"break" instead if the loop should end immediately. Of course, anyone
writing code like that in *my* shop gets taken out back and shot.
 
Z

zerg

Joshua said:
Similarly, the syntax doesn't feel right, especially since
|new int[x](10)| and |new StringBuilder[x](10)| are using the same
syntax to do two different things: the first a shorthand in essence for
|foo = 10| and the latter for |new StringBuilder(10)|.

That's like complaining that new Integer(10) and new Stringbuilder(10)
have the same syntax but do very different things with the "10".
 
A

Andreas Leitgeb

Joshua Cranmer said:
I would agree that multiple-evaluation makes more sense as a use case,
BUT to do so would be to completely ignore Java's basic syntax style.
Not sure if I understood this point. Isn't the thread about changing
(or at least adding to) Java's syntax? So it's trivially true that it
violates the current set of rules. Which of the current rules would
such a new be at odds with?
So multiple-evaluation is the ideal case but also a non-starter.
I'm aware of some disadvantages, but I didn't let them stop
me from dreaming a bit :)
 
J

Joshua Cranmer

Andreas said:
Not sure if I understood this point. Isn't the thread about changing
(or at least adding to) Java's syntax? So it's trivially true that it
violates the current set of rules. Which of the current rules would
such a new be at odds with?

Let me clarify a bit.

The idea is that the expression is evaluated "as it is seen." So that
means that |new X[<expr 1>](<expr 2>)| will invoke in order <expr 1>,
|new X[<expr 1>]|, <expr 2> and then the construction part. In
particular, they would all be logically evaluated but once. The only
place where an expression is taking to be invoked multiple times is
where it is implicitly part of a loop statement--i.e. the condition of
for, while, and do/while loops, as well as the increment statement of
the for loop.
 
J

Joshua Cranmer

zerg said:
Joshua said:
Similarly, the syntax doesn't feel right, especially since
|new int[x](10)| and |new StringBuilder[x](10)| are using the same
syntax to do two different things: the first a shorthand in essence
for |foo = 10| and the latter for |new StringBuilder(10)|.

That's like complaining that new Integer(10) and new Stringbuilder(10)
have the same syntax but do very different things with the "10".

It was hard to come with a good example; the basic idea was that one
refers in essence to assignment and the other to construction.

A better example would be
|new int[x](10)| creates an array filled with x's while |new
LinkedList[x](list)| creates an array filled with copies of new
LinkedList(list).

Note that in that case the syntax is ambiguous: am I filling the list
with copies of list or actual references to list? Good idioms should
make meaning clear, even if the syntax is foreign. New syntax should
reflect this design. |for (String s : strings)| may be new to a user,
but it is immediately clear (if strings is an array) that s will be
referring to each value in the array.
 
B

bbound

[lots of ideas deleted]
ArrayList literals. Maybe use [{item, item, item}] as the syntax (it
isn't currently legal with some different meaning, so no clash there).
Right now, we have the cumbersome
List<Foo> list = new ArrayList<Foo>();
Collections.addAll(list, item, item, item);
but, not to put too fine a point on it, that freaking blows.
List<Foo> list = [{item, item, item}];
is much nicer.

In between is the currently legal, and barely more complex,

List <Foo> list =
   Arrays.asList( { aFoo, anotherFoo, moreFoo, enoughFooAlready } );

That's only thirteen characters longer than your suggestion, or a mere six
with static import:

List <Foo> list = asList( { aFoo, anotherFoo, moreFoo, enoughFooAlready } );

or a mere four with:

List <Foo> list = asList( aFoo, anotherFoo, moreFoo, enoughFooAlready );

and given the simplicity and very explicit self-documenting nature of
'asList', I doubt very much that the language will undergo a change just to
save four characters.

Methinks we're at least missing an array-taking/varargs constructor
for the common collection classes. And putting a collection factory
method in neither a collection class nor Collections amounts to hiding
it. :p

Map is the really annoying case, though. If you want a map initialized
with particular mappings, you tend to wind up with an initializer
block or some other such complexity.

A constructor that expects an array of two-element arrays of Object
(and throws IllegalArgumentException/ClassCastException as
appropriate), added to the common map implementations, would go a long
way:

Map<K,V> map = new HashMap<K,V>({{k1,v1}, {k2,v2}, {k3,v3}});

Or even add a HashMap literal, say

Map<K,V> = {[k1, v1], [k2, v2], [k3, v3]};

whose type is HashMap<K,V> with K the most specific common supertype
of the key expressions in the literal and V the most specific common
supertype of the values.

While they're at it, they might add a Pair<K,V> type, with [x, y]
being a pair literal, and put some Pair using methods in the APIs.
Map<K,V>s might get put(Pair<K,V>) equivalent to put(pair.getKey,
pair.getValue), and Map.Entry might implement Pair if Pair is an
interface.
 
A

Andreas Leitgeb

Joshua Cranmer said:
Let me clarify a bit.
particular, they would all be logically evaluated but once. The only
place where an expression is taking[taken?] to be invoked multiple
times is where it is implicitly part of a loop statement--i.e. the
condition of for, while, and do/while loops, as well as the increment
statement of the for loop.

The argumentation depends on an (admittedly wholly agreeable) premise,
namely: "we do not want to make "new" another loop statement"

Case closed for me :)
 
Z

zerg

Joshua said:
zerg said:
Joshua said:
Similarly, the syntax doesn't feel right, especially since
|new int[x](10)| and |new StringBuilder[x](10)| are using the same
syntax to do two different things: the first a shorthand in essence
for |foo = 10| and the latter for |new StringBuilder(10)|.

That's like complaining that new Integer(10) and new Stringbuilder(10)
have the same syntax but do very different things with the "10".

It was hard to come with a good example; the basic idea was that one
refers in essence to assignment and the other to construction.

Depending on whether the cell type was primitive or not. Primitives have
always been black sheep of sorts in Java. :)
A better example would be
|new int[x](10)| creates an array filled with x's

In what, C#? :)

In my proposal, it would create an array filled with 10s. :)
Note that in that case the syntax is ambiguous: am I filling the list
with copies of list or actual references to list?

That would depend on what the constructor did.

Perhaps it would be better to have two syntaxes, though: new foo[]{val}
to assign primitives or to fill reference cells by reference, and (args)
for construction. Then new List[x](list) copies the list x times and new
List[x]{list} populates the arrays with references to the existing list. :)
 
A

Arne Vajhøj

zerg said:
Is there a reason for dumping a large load of hostility into the
newsgroup? Generally speaking, there isn't much point posting if you
have nothing genuinely constructive to say.

I think he had excellent arguments why the proposed changed did
not bring sufficient value to justify a change.

Arne
 
A

Arne Vajhøj

Patricia said:
Eric said:
zerg said:
[...]
It occurs to me that it might be somewhat-useful if Java added some
syntax (which wouldn't break source compatibility, I don't think) as
a shortcut for constructing multidimensional arrays and for
initializing arrays with all-identical elements other than zero,
null, or false.

Proposed:

new X[x][y] -> an array of y X[] references, each pointing to a
distinct new X[x] instead of to null.

Sorry, that syntax is already taken: it constructs an array
of x X[] references, each pointing to a distinct array of y X
references, all null.
...

I like initializer blocks as a very general solution to this class of
problem.

X[] myXArray = new X[y];
{
for(int i=0; i<myXArray.length; i++){
myXArray = new X();
}
}

> This solution avoids extra syntax, and yet keeps the full initialization
> together, rather than spreading it between the declarations and the
> constructor. It is far more powerful than any special case syntax could
> be.

Why do I think of the term clo.... ?
int[] myInts = new int[10];
{
Arrays.fill(myInts, 1);
}

In this case I find it difficult to see the value of the
curle brackets.

:)

Arne
 
A

Arne Vajhøj

Andreas said:
Patricia Shanahan said:
I like initializer blocks as a very general solution to this class of
problem.
If you've devised some idiom for this kind of job, you effectively
agree to zerg, that there is indeed some use for that job. :)
X[] myXArray = new X[y];
{
for(int i=0; i<myXArray.length; i++){
myXArray = new X();
}
}


X[] myXArray = new X[y]();
int[] myInts = new int[10];
{
Arrays.fill(myInts, 1);
}

int[] myInts = new int[10](1);


No.

Patricias solution is much more general.

It could be:

int[] myInts = new int[10];
{
for(int i = 0; i < myInts.length; i++) myInt = i * i + 1;
}

Arne
 
A

Andreas Leitgeb

A somewhat late resurrection of that thread...
Is your newsfeed late to show those articles
only now?
No.
Patricias solution is much more general.

Of course it is! The discussion wasn't about making it more
general, but about making a less general but (believed)more
common pattern syntactically simpler.
It could be:
int[] myInts = new int[10];
{
for(int i = 0; i < myInts.length; i++) myInt = i * i + 1;
}


I dislike these nested blocks. They always make me look for
something in the previous lines, like a "for"/"if"/"while"/...
or a new SomeClass(...) (though without brackets and semicolon) -
only initializer blocks in classes are excepted, because they
happen in quite a different context.

In your example, it's even entirely unnecessary since the only
local variable in that block is already local to the "for".

PS: just recently a coworker asked me, if there wasn't a way
to initialize a freshly created multidimensional array with
a constant value different from 0 without iterating all the
arrays (and nested arrays).
 
P

Patricia Shanahan

Andreas said:
A somewhat late resurrection of that thread...
Is your newsfeed late to show those articles
only now?
No.
Patricias solution is much more general.

Of course it is! The discussion wasn't about making it more
general, but about making a less general but (believed)more
common pattern syntactically simpler.
It could be:
int[] myInts = new int[10];
{
for(int i = 0; i < myInts.length; i++) myInt = i * i + 1;
}


I dislike these nested blocks. They always make me look for
something in the previous lines, like a "for"/"if"/"while"/...
or a new SomeClass(...) (though without brackets and semicolon) -
only initializer blocks in classes are excepted, because they
happen in quite a different context.

In your example, it's even entirely unnecessary since the only
local variable in that block is already local to the "for".


Who said "local"? My code was intended for initializing a non-static
field. I agree that the braces are unnecessary, and should be removed,
when initializing a local variable. For a static field, "static" should
be added immediately before the opening brace.

Patricia
 

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

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,129
Latest member
FastBurnketo
Top