Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Inserting In a List

133 views
Skip to first unread message

subhaba...@gmail.com

unread,
Apr 2, 2013, 6:11:53 AM4/2/13
to
Dear Group,

I am taking out the files in my desktop folder, as,

File folder = new File("C:\\Users\\subhabrata\\Desktop");

Next, I am trying to take them out one by one as using for loop and name
of each file is converted to String,

for( File name :folder.listFiles()){
String s1=name.toString();
System.out.println("####"+s1);
System.out.print( name );
}

Till this there is no issue, now I am trying to insert name of all the files in an array, generally it can be done, as,

ArrayList<String> myList = new ArrayList<String>();
myList.add(s1);

But the problem I am facing is, if I put it as,

for( File name :folder.listFiles()){
String s1=name.toString();
System.out.println("####"+s1);
System.out.print( name );
ArrayList<String> myList = new ArrayList<String>();
myList.add(s1);
}

I am getting name of files individually but I want to see them as the whole bunch like,

myList=["string1","string2","string3",...."StringN"]

My aim is to check the names then in another for loop and if match is not found with some defined name update the list.

I am slightly new in Java so if anyone can kindly suggest how I should address it.

Regards,
Subhabrata.

Roedy Green

unread,
Apr 2, 2013, 6:59:22 AM4/2/13
to
On Tue, 2 Apr 2013 03:11:53 -0700 (PDT), subhaba...@gmail.com
wrote, quoted or indirectly quoted someone who said :

>I am getting name of files individually but I want to see them as the whole bunch like,
>
>myList=["string1","string2","string3",...."StringN"]

you will need a loop that runs over the list and builds the combined
string.
--
Roedy Green Canadian Mind Products http://mindprod.com
Motors make noise, and that tells you about the feelings and attitudes
that went into it. Something was more important than sensory pleasure --
nobody would invent a chair or dish that smelled bad or that made horrible
noises -- why were motors invented noisy? How could they possibly be
considered complete or successful inventions with this glaring defect?
Unless, of course, the aggressive, hostile, assaultive sound actually served
to express some impulse of the owner.
~ Philip Slater (born: 1927 age: 85)
The Wayward Gate: Science and the Supernatural

Arved Sandstrom

unread,
Apr 2, 2013, 7:27:33 AM4/2/13
to
This comes up every so often. Guava and Apache StringUtils have
join-type methods for concatenating list elements with a delimiter of
your choice.

Fact is, though, if you just want a readable debugging print of your
List, did you not simply try

System.out.println(myList);

AHS
Message has been deleted

Arved Sandstrom

unread,
Apr 2, 2013, 7:59:52 AM4/2/13
to
On 04/02/2013 08:40 AM, Stefan Ram wrote:
> subhaba...@gmail.com writes:
>> for( File name :folder.listFiles()){
>> String s1=name.toString();
>> System.out.println("####"+s1);
>> System.out.print( name );
>> ArrayList<String> myList = new ArrayList<String>();
>> myList.add(s1);
>> }
>
> I see two answers in this NG both not mentioning what is
> sticking out like a sore thumb from this code: The line
>
> ArrayList<String> myList = new ArrayList<String>();
>
> is within the for-loop, while it obviously should appear in
> front of it. (There might be other issues I am not aware of,
> but this one I saw immediately.)
>
You've got a point there. :-) Well, many pairs of eyes in a review is
always better than one.

AHS

Joerg Meier

unread,
Apr 2, 2013, 8:35:06 AM4/2/13
to
On Tue, 2 Apr 2013 03:11:53 -0700 (PDT), subhaba...@gmail.com wrote:

> I am taking out the files in my desktop folder, as,

> [...]

> I am getting name of files individually but I want to see them as the whole bunch like,

> myList=["string1","string2","string3",...."StringN"]

You need to move the list assignment out of the loop, like so:

final File folder = new File("G:\\Media\\TV Show");
final ArrayList<String> myList = new ArrayList<String>();
for (final File name : folder.listFiles()) {
final String s1 = name.toString();
System.out.println("####" + s1);
System.out.print(name);
myList.add(s1);
}

Otherwise, you create a new, empty list for every file name, and delete the
previous one.

You can then print out your list like so:

System.out.println(myList);

Which is really short hand for the more generic version:

System.out.println(Arrays.toString(myList.toArray()));

> My aim is to check the names then in another for loop and if match is not found with some defined name update the list.

It's really not clear to me what you mean by that. You will need to restate
it or explain it in more detail.

Liebe Gruesse,
Joerg

--
Ich lese meine Emails nicht, replies to Email bleiben also leider
ungelesen.

Steven Simpson

unread,
Apr 2, 2013, 8:53:00 AM4/2/13
to
On 02/04/13 11:11, subhaba...@gmail.com wrote:
> for( File name :folder.listFiles()){
> String s1=name.toString();
> System.out.println("####"+s1);
> System.out.print( name );
> ArrayList<String> myList = new ArrayList<String>();
> myList.add(s1);
> }

(Stefan has already noted that the list must be created before the
loop. What you have here is one list created per item in the folder,
and each of these lists is discarded.)

> I am getting name of files individually but I want to see them as the whole bunch like,
>
> myList=["string1","string2","string3",...."StringN"]

(Arved and Roedy have mentioned some ways to get this, though I think
you are after something different. Read on...)

> My aim is to check the names then in another for loop and if match is not found with some defined name update the list.

Your loop seems to have two purposes: 1) display all items in a certain
format; 2) build an internal List object.

Perhaps I've misinterpreted your aim, but your wish to generate a list
of names in a string with a given format leads me to think you're under
the impression that you need to display the names somehow in order to
perform the check you mention. This is not necessary (nor useful,
except for purposes of diagnosing problems). You should do the check on
the List object, not on the formatted String.

Firstly, if you must create a List, there's a quick way to create a
fixed-size one from the array provided by listFiles():

List<File> files = Arrays.asList(folder.listFiles());

Note that this is a list of File, not String; the code below does not
need a List<String>. If you really do need a List<String>, you could do
something similar with folder.list() instead of folder.listFiles().

Next, you could scan the List for a matching file. Loop over it, and
record when you find it:

boolean found = false;
for (File file : files) {
if (file.getName().equals("foo")) {
found = true;
break; // No need to go further.
}
}

However, unless you need to keep the List around for other purposes, you
could just use the array directly from listFiles():

boolean found = false;
for (File file : folder.listFiles()) {
if (file.getName().equals("foo")) {
found = true;
break; // No need to go further.
}
}

But it would be even simpler, if you're just looking for a particular
leafname (like "foo"), rather than a leafname matching a given pattern
(like anything beginning with "foo"), to create a File object
representing that name, and checking whether the file exists:

File candidate = new File(folder, "foo");
boolean found = candidate.exists();

Note that, confusingly, java.io.File represents a file name, not a file,
so 'new File(...)' does not actually create a file.

> and if match is not found with some defined name update the list.

Not sure how you intend to update the List. If it's supposed to
represent the list of files in the folder, updating the List won't
create the missing file. Perhaps you want the rest of the program to
suppose it exists; I don't know.

If you really do want to update the list, you'll have to create it as
one you can resize:

List<File> files = new ArrayList<File>(Arrays.asList(folder.listFiles()));

Read this inside out:

1. listFiles(): Get the list of filenames as an array.
2. asList(): Create a 'List view' of the array.
3. new ArrayList(): Create a modifiable list with the same contents as
the array.




--
ss at comp dot lancs dot ac dot uk

lipska the kat

unread,
Apr 2, 2013, 10:08:53 AM4/2/13
to
On 02/04/13 13:35, Joerg Meier wrote:
> On Tue, 2 Apr 2013 03:11:53 -0700 (PDT), subhaba...@gmail.com wrote:
>
>> I am taking out the files in my desktop folder, as,
>
>> [...]
>
>> I am getting name of files individually but I want to see them as the whole bunch like,
>
>> myList=["string1","string2","string3",...."StringN"]
>
> You need to move the list assignment out of the loop, like so:
>
> final File folder = new File("G:\\Media\\TV Show");
> final ArrayList<String> myList = new ArrayList<String>();
> for (final File name : folder.listFiles()) {
> final String s1 = name.toString();
> System.out.println("####" + s1);
> System.out.print(name);
> myList.add(s1);
> }

Just as a matter of interest what's with all the finals

particularly

for (final File name : folder.listFiles())

Despite initial appearances this is indeed legal as the
assignment is made multiple times but from the same statement.

Given that the final keyword is, aside from a flag to the compiler for
possible optimization, largely documentary, what is the point of making
name final.

In fact what does peppering the code with finals do to make it easily
understandable to an inexperienced developer ?

lipska

--
Lipska the Kat�: Troll hunter, sandbox destroyer
and farscape dreamer of Aeryn Sun

Roedy Green

unread,
Apr 2, 2013, 10:10:53 AM4/2/13
to
On Tue, 2 Apr 2013 03:11:53 -0700 (PDT), subhaba...@gmail.com
wrote, quoted or indirectly quoted someone who said :

>myList=["string1","string2","string3",...."StringN"]


FastCat, my replacement for StringBuilder has a toCommaList that
exports a comma-separated set of strings in one long string.

see http://mindprod.com/products.html#FASTCAT

Lew

unread,
Apr 2, 2013, 1:46:12 PM4/2/13
to
subhaba...@gmail.com wrote:
> I am taking out the files in my desktop folder, as,

"Taking out" I understood initially as "deleting", but I gather you mean "printing" or
"displaying".


> File folder = new File("C:\\Users\\subhabrata\\Desktop");

You can also use forward slashes.

> Next, I am trying to take them out one by one as using for loop and name
> of each file is converted to String,

If you indented properly your scope issues would be easier to see. The first block
doesn't have any, but the one further down does.

> for( File name :folder.listFiles()){
> String s1=name.toString();
> System.out.println("####"+s1);
> System.out.print( name );
> }

I should think you'd use 'getPath()' or 'getName()' on the 'name' instance.

> Till this there is no issue, now I am trying to insert name of all the files
> in an array, generally it can be done, as,

> ArrayList<String> myList = new ArrayList<String>();

That is not an array, that is a 'List'.

> myList.add(s1);

> But the problem I am facing is, if I put it as,

Again, proper indentation would reveal any scope issues.

> for( File name :folder.listFiles()){
> String s1=name.toString();
> System.out.println("####"+s1);
> System.out.print( name );
> ArrayList<String> myList = new ArrayList<String>();
> myList.add(s1);
> }

Now here you have a scope issue. You create a new 'List' in each iteration, add only
one item to it, then throw it away. Nowhere do you create a 'List' that survives one
loop iteration.

> I am getting name of files individually but I want to see them as the whole bunch like,

You show no code that demonstrates how you determine what "you" are "getting".

Please follow
http://sscce.org/

> myList=["string1","string2","string3",...."StringN"]

In that case, declare your 'List' in a scope that survives the loop.

> My aim is to check the names then in another for loop and if match
> is not found with some defined name update the list.

Study "scope" and "access" in Java.

> I am slightly new in Java so if anyone can kindly suggest how I should address it.

What is "slightly"?

--
Lew

markspace

unread,
Apr 2, 2013, 2:28:12 PM4/2/13
to
On 4/2/2013 10:46 AM, Lew wrote:

> subhaba...@gmail.com wrote:
>> I am taking out the files in my desktop folder, as,

> "Taking out" I understood initially as "deleting", but I gather you mean "printing" or
> "displaying".

I think he means "reading." As in he reads the file entries with these
lines of code:

>> File folder = new File("C:\\Users\\subhabrata\\Desktop");
>> ... folder.listFiles()...

>
>> Next, I am trying to take them out one by one as using for loop and name
>> of each file is converted to String,

Again, "take... out" for reading from an array.

To subhaba: "Iterate over" is often used to describe reading from an
array in a loop (for-loop or other loop).

Robert Klemme

unread,
Apr 2, 2013, 3:06:25 PM4/2/13
to
On 04/02/2013 04:08 PM, lipska the kat wrote:

> Just as a matter of interest what's with all the finals
>
> particularly
>
> for (final File name : folder.listFiles())
>
> Despite initial appearances this is indeed legal as the
> assignment is made multiple times but from the same statement.
>
> Given that the final keyword is, aside from a flag to the compiler for
> possible optimization, largely documentary, what is the point of making
> name final.

It helps avoid accidental reassignment. And it helps distinguish
unchanged from changed variables.

> In fact what does peppering the code with finals do to make it easily
> understandable to an inexperienced developer ?

I believe in using "final" pretty often as it will immediately indicate
which local variables are constant for a method call and which are
modified all the time. Plus, with "final" you can easier catch errors
in control flow:

final String x;

if ( someCondition() ) {
x = y.toString();
}
else {
if ( someOtherCondition() ) {
x = "foo";
}
// forgot the else branch here
x = "bar";
}

System.out.println("We got " + x);

Generally I find "finally" quite useful - apparently significantly more
useful than you do. :-)

Kind regards

robert

Eric Sosman

unread,
Apr 2, 2013, 4:00:28 PM4/2/13
to
Let's not give the impression that "iterate" or even "iterate
over" implies read-only activities. If it did, why would the
Iterator interface specify a remove() method? :)

Typical usage is "The code iterates over the array (or list,
or sequence, or collection), doing thus-and-such." It's the
thus-and-such part that indicates whether reading or writing (or
both, or something more complicated) is involved; iteration is
just the procedure for making the visits, not their nature.

"Iterate over the array, looking for the minimum value."

"Iterate over the array, converting all the values from
degrees to radians."

If the iteration is simple or obvious (or irrelevant) it
probably doesn't get mentioned at all: The above would likely
be "find the minimum" and "convert degrees to radians." The
main reason to mention the iteration itself would be if there's
something special or unusual about it:

"The list is sorted from smallest to largest. Iterate
backwards to output the items in descending order."

"Basic cocktail-shaker sort: Iterate over the list,
exchanging adjacent pairs of elements that are out of order.
Then make another pass, this time iterating in the opposite
direction. Repeat, alternating directions, until a pass
makes no exchanges."

--
Eric Sosman
eso...@comcast-dot-net.invalid

Joerg Meier

unread,
Apr 2, 2013, 4:09:13 PM4/2/13
to
On Tue, 02 Apr 2013 15:08:53 +0100, lipska the kat wrote:

> Just as a matter of interest what's with all the finals

final further describes what is happening - namely, whereas "File name"
says "I'm making a local variable named name of the type File", "final File
name" says "I'm making a local variable named name of the type File,
assigning it here, and then it will always stay that". In general, I prefer
being more clear over being less clear, at the cost of being more verbose.

> particularly

> for (final File name : folder.listFiles())

> Despite initial appearances this is indeed legal as the
> assignment is made multiple times but from the same statement.

In this case, it signals that inside the loop, name is not reassigned.
>
> Given that the final keyword is, aside from a flag to the compiler for
> possible optimization, largely documentary, what is the point of making
> name final.

> In fact what does peppering the code with finals do to make it easily
> understandable to an inexperienced developer ?

It doesn't at all. I have my IDE set to automatically make final what it
can, because I'm often lazy and forget to do it myself, and didn't even
think about it when copying the code back (as for why I put it in my IDE in
the first place, I wanted to confirm that Sysout(myList) was indeed
identical to Sysout(Arrays.toString(myList.toArray())).

So, I honestly didn't even realize that my IDE put in the finals, because
I'm so used to it by now. Didn't give it any more thought than I gave the
fact that my IDE did proper code formatting on it.

In retrospect, without an explanation, it's probably more confusing than
helpful to a newbie, so it's good that you brought the issue up.

Eric Sosman

unread,
Apr 2, 2013, 4:41:00 PM4/2/13
to
On 4/2/2013 3:06 PM, Robert Klemme wrote:
>[...]
> I believe in using "final" pretty often as it will immediately indicate
> which local variables are constant for a method call and which are
> modified all the time. [...]

De gustibus non disputandum est, but I think "final" should
be reserved for things that *mustn't* change, and shouldn't just
be pasted on to anything that happens to remain constant in the
code's current incarnation. When considering a change to some
code I might see

Thing thing = getThing();
// ... code that doesn't happen to change `thing'

or I might see

final Thing thing = getThing();
// ... code that (obviously) doesn't change `thing'

In the first case I might think about inserting, say,

if (thing == null)
thing = fallbackThing();

... while in the second case I wouldn't even consider it: I
would suppose that the code relied on `thing' being exactly
what getThing() had returned, perhaps in some way and for some
reason not clear to me.

But, as I said above, de gustibus.

> Generally I find "finally" quite useful - apparently significantly more
> useful than you do. :-)

"finally" is a Godsend -- but did you mean "final"?

--
Eric Sosman
eso...@comcast-dot-net.invalid

Martin Gregorie

unread,
Apr 2, 2013, 5:06:47 PM4/2/13
to
Its also not clear to me whether the OP is expecting some form of sorted
list of filenames. If he is expecting that, it would be best to use a
TreeMap<String> rather than an ArrayList<String> to store the filenames.


--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |

Eric Sosman

unread,
Apr 2, 2013, 6:22:55 PM4/2/13
to
On 4/2/2013 5:06 PM, Martin Gregorie wrote:
>[...]
> Its also not clear to me whether the OP is expecting some form of sorted
> list of filenames. If he is expecting that, it would be best to use a
> TreeMap<String> rather than an ArrayList<String> to store the filenames.

Is there a reason to prefer TreeMap (or other SortedMap) over
accumulate-disordered-and-sort-afterward?

--
Eric Sosman
eso...@comcast-dot-net.invalid

Martin Gregorie

unread,
Apr 2, 2013, 6:52:20 PM4/2/13
to
On Tue, 02 Apr 2013 18:22:55 -0400, Eric Sosman wrote:

> On 4/2/2013 5:06 PM, Martin Gregorie wrote:
>>[...]
>> Its also not clear to me whether the OP is expecting some form of
>> sorted list of filenames. If he is expecting that, it would be best to
>> use a TreeMap<String> rather than an ArrayList<String> to store the
>> filenames.
>
> Is there a reason to prefer TreeMap (or other SortedMap) over
> accumulate-disordered-and-sort-afterward?
>
I think so, yes, because none of File's list() and listFiles() methods
guarantee the order of the returned files. By using TreeMap or equivalent
the OP gets the sort for free, should it be required.

I use it a lot, both for that and because accessing stored objects by key
from a TreeMap is almost certainly faster than scanning an ArrayMap
unless it contains very few objects indeed.

Arne Vajhøj

unread,
Apr 2, 2013, 8:03:14 PM4/2/13
to
The performance optimization benefits of final is a myth
solid founded in how JVM's from the 1990's worked.

The generous usage of final is an attempt to make
Java a more functional language.

I don't like it. If I want to program in a functional style, then
I would pick a functional language.

Arne


Joerg Meier

unread,
Apr 2, 2013, 8:04:19 PM4/2/13
to
On Tue, 2 Apr 2013 22:52:20 +0000 (UTC), Martin Gregorie wrote:

> On Tue, 02 Apr 2013 18:22:55 -0400, Eric Sosman wrote:
>> On 4/2/2013 5:06 PM, Martin Gregorie wrote:
>>>[...]
>>> Its also not clear to me whether the OP is expecting some form of
>>> sorted list of filenames. If he is expecting that, it would be best to
>>> use a TreeMap<String> rather than an ArrayList<String> to store the
>>> filenames.
>> Is there a reason to prefer TreeMap (or other SortedMap) over
>> accumulate-disordered-and-sort-afterward?
> I think so, yes, because none of File's list() and listFiles() methods
> guarantee the order of the returned files. By using TreeMap or equivalent
> the OP gets the sort for free, should it be required.

For free ? The cost is just distributed amongst the insert calls, and is
likely considerably higher than with an unsorted list that has a single
sort call once it is filled. SortedMaps are for things that need sorting
accessible before all elements are inserted, which really isn't the case
here.

> I use it a lot, both for that and because accessing stored objects by key
> from a TreeMap is almost certainly faster than scanning an ArrayMap
> unless it contains very few objects indeed.

Java doesn't have ArrayMaps. TreeMaps are O(log(n)) for get while a HashMap
alternative would be O(1). I don't think Java includes any map with
behaviour as ill coded as what you describe. Frankly, I'm having trouble
imagining any modern language having something quite that horrible. Even
LinkedList-Map-combinations usually are backed with some sort of HashMap.

I don't mean to be rude, but it seems like you have lot of misconception
about how data structures work in anything more than school/class level
implementations.

Arne Vajhøj

unread,
Apr 2, 2013, 8:08:39 PM4/2/13
to
On 4/2/2013 3:06 PM, Robert Klemme wrote:
> On 04/02/2013 04:08 PM, lipska the kat wrote:
>> Just as a matter of interest what's with all the finals
>>
>> particularly
>>
>> for (final File name : folder.listFiles())
>>
>> Despite initial appearances this is indeed legal as the
>> assignment is made multiple times but from the same statement.
>>
>> Given that the final keyword is, aside from a flag to the compiler for
>> possible optimization, largely documentary, what is the point of making
>> name final.
>
> It helps avoid accidental reassignment. And it helps distinguish
> unchanged from changed variables.

That is a nice theory.

I am a bit skeptic about the real world benefits.

In the example provided it would simply never happen.

Arne

Arne Vajhøj

unread,
Apr 2, 2013, 8:20:15 PM4/2/13
to
On 4/2/2013 8:04 PM, Joerg Meier wrote:
> On Tue, 2 Apr 2013 22:52:20 +0000 (UTC), Martin Gregorie wrote:
>
>> On Tue, 02 Apr 2013 18:22:55 -0400, Eric Sosman wrote:
>>> On 4/2/2013 5:06 PM, Martin Gregorie wrote:
>>>> [...]
>>>> Its also not clear to me whether the OP is expecting some form of
>>>> sorted list of filenames. If he is expecting that, it would be best to
>>>> use a TreeMap<String> rather than an ArrayList<String> to store the
>>>> filenames.
>>> Is there a reason to prefer TreeMap (or other SortedMap) over
>>> accumulate-disordered-and-sort-afterward?
>> I think so, yes, because none of File's list() and listFiles() methods
>> guarantee the order of the returned files. By using TreeMap or equivalent
>> the OP gets the sort for free, should it be required.
>
> For free ? The cost is just distributed amongst the insert calls, and is
> likely considerably higher than with an unsorted list that has a single
> sort call once it is filled.

It is not that obvious to me that:

n O(1) + 1 O(nlogn) is that much faster than n log(n)

> SortedMaps are for things that need sorting
> accessible before all elements are inserted, which really isn't the case
> here.
>
>> I use it a lot, both for that and because accessing stored objects by key
>> from a TreeMap is almost certainly faster than scanning an ArrayMap
>> unless it contains very few objects indeed.
>
> Java doesn't have ArrayMaps. TreeMaps are O(log(n)) for get while a HashMap
> alternative would be O(1). I don't think Java includes any map with
> behaviour as ill coded as what you describe. Frankly, I'm having trouble
> imagining any modern language having something quite that horrible. Even
> LinkedList-Map-combinations usually are backed with some sort of HashMap.
>
> I don't mean to be rude, but it seems like you have lot of misconception
> about how data structures work in anything more than school/class level
> implementations.

I think Martin has a lot of experience.

But I think he got this post garbled up a bit.

As you correctly state then there are no ArrayMap. I am not even sure
what such a beast would actually do.

I also somewhat suspect that he really meant TreeSet not TreeMap as
I can not see any key value pair here.

Arne


Eric Sosman

unread,
Apr 2, 2013, 9:03:55 PM4/2/13
to
On 4/2/2013 8:20 PM, Arne Vajh�j wrote:
> On 4/2/2013 8:04 PM, Joerg Meier wrote:
>> On Tue, 2 Apr 2013 22:52:20 +0000 (UTC), Martin Gregorie wrote:
>>
>>> On Tue, 02 Apr 2013 18:22:55 -0400, Eric Sosman wrote:
>>>> On 4/2/2013 5:06 PM, Martin Gregorie wrote:
>>>>> [...]
>>>>> Its also not clear to me whether the OP is expecting some form of
>>>>> sorted list of filenames. If he is expecting that, it would be best to
>>>>> use a TreeMap<String> rather than an ArrayList<String> to store the
>>>>> filenames.
>>>> Is there a reason to prefer TreeMap (or other SortedMap) over
>>>> accumulate-disordered-and-sort-afterward?
>>> I think so, yes, because none of File's list() and listFiles() methods
>>> guarantee the order of the returned files. By using TreeMap or
>>> equivalent
>>> the OP gets the sort for free, should it be required.
>>
>> For free ? The cost is just distributed amongst the insert calls, and is
>> likely considerably higher than with an unsorted list that has a single
>> sort call once it is filled.
>
> It is not that obvious to me that:
>
> n O(1) + 1 O(nlogn) is that much faster than n log(n)

By design, O() obscures all the coefficients. If you were
to say that n*log(n) and 9999999999999999999999999999*n*log(n)
are both O(n*log(n)) you would be right -- but if you were to
claim the former was not "that much faster" than the latter you
would be wrong by a factor of 9999999999999999999999999999.

... and that's the gist of my question: It seems to me likely
that the actual time to sort an ArrayList of large-ish N size will
be less than the time to build a TreeMap (BTW, Martin probably
meant TreeSet) of the same N items. Argument: The TreeSet expends
effort in keeping itself always sorted all the time, while the
ArrayList has the freedom to be disordered up until the end, and
then to impose an ordering just once. The ArrayList is asked to
present one sorted version of N items, while the TreeSet must
offer sorted versions of 1,2,3,...,N items. If the intermediate
orderings are not required, I don't see much reason to compute them.

By the way, the ArrayList will use less memory -- but both
will use O(n) in all, so who cares? :-)

For this insight I will charge you only O(1) pfennigs. ;-)

--
Eric Sosman
eso...@comcast-dot-net.invalid

Eric Sosman

unread,
Apr 2, 2013, 9:08:26 PM4/2/13
to
On 4/2/2013 6:52 PM, Martin Gregorie wrote:
> On Tue, 02 Apr 2013 18:22:55 -0400, Eric Sosman wrote:
>
>> On 4/2/2013 5:06 PM, Martin Gregorie wrote:
>>> [...]
>>> Its also not clear to me whether the OP is expecting some form of
>>> sorted list of filenames. If he is expecting that, it would be best to
>>> use a TreeMap<String> rather than an ArrayList<String> to store the
>>> filenames.
>>
>> Is there a reason to prefer TreeMap (or other SortedMap) over
>> accumulate-disordered-and-sort-afterward?
>>
> I think so, yes, because none of File's list() and listFiles() methods
> guarantee the order of the returned files. By using TreeMap or equivalent
> the OP gets the sort for free, should it be required.

"For free" seems to have swept a few coins under the rug.
The sort is by no means "free," since computational effort is
expended in producing it. My question is why one should prefer
keep-it-always-sorted-even-during-the-accumulation-phase over
just-let-the-chips-fall-and-sort-them-later. It seems to me the
latter is likely to be cheaper in both time and memory, and that
the one extra line of code ("Collections.sort(list)") is not an
overwhelming burden on the programmer.

> I use it a lot, both for that and because accessing stored objects by key
> from a TreeMap is almost certainly faster than scanning an ArrayMap
> unless it contains very few objects indeed.

Sorry: "ArrayMap"?

--
Eric Sosman
eso...@comcast-dot-net.invalid

Joshua Cranmer 🐧

unread,
Apr 2, 2013, 9:26:06 PM4/2/13
to
On 4/2/2013 7:20 PM, Arne Vajhøj wrote:
> On 4/2/2013 8:04 PM, Joerg Meier wrote:
>> On Tue, 2 Apr 2013 22:52:20 +0000 (UTC), Martin Gregorie wrote:
>>
>>> On Tue, 02 Apr 2013 18:22:55 -0400, Eric Sosman wrote:
>>>> On 4/2/2013 5:06 PM, Martin Gregorie wrote:
>>>>> [...]
>>>>> Its also not clear to me whether the OP is expecting some form of
>>>>> sorted list of filenames. If he is expecting that, it would be best to
>>>>> use a TreeMap<String> rather than an ArrayList<String> to store the
>>>>> filenames.
>>>> Is there a reason to prefer TreeMap (or other SortedMap) over
>>>> accumulate-disordered-and-sort-afterward?
>>> I think so, yes, because none of File's list() and listFiles() methods
>>> guarantee the order of the returned files. By using TreeMap or
>>> equivalent
>>> the OP gets the sort for free, should it be required.
>>
>> For free ? The cost is just distributed amongst the insert calls, and is
>> likely considerably higher than with an unsorted list that has a single
>> sort call once it is filled.
>
> It is not that obvious to me that:
>
> n O(1) + 1 O(nlogn) is that much faster than n log(n)

The received wisdom I've heard would say that ArrayList is superior here
to a TreeMap. Recall that a TreeMap is a self-balancing red-black tree.
This means that every access of a node requires chasing at most O(lg n)
pointers, and that adding elements could require as many as O(lg n)
rebalancing operations. Compare this to ArrayList and the corresponding
sort technique, which is a merge sort. The array options chase
effectively no pointers (internal to the data structure), so the
accesses are predictable to the cache lines. As a result, you would
expect that the ArrayList+sort method is slightly faster in the general
case than the TreeMap implementation.

Another factor to keep in mind is algorithmic performance if the data
isn't actually uniformly random. If the input data is already sorted,
the sort function will likely achieve its best possible performance,
while the tree map will likely achieve its worst possible performance.
Since sorted data tends to be more realistic in practice than true
random, sorted lists actually have some things going for them. :-)

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

Arne Vajhøj

unread,
Apr 2, 2013, 9:26:47 PM4/2/13
to
Yes.

But given same big-O I would expect some solid reasons for a
big difference in coefficients before I assume a big difference
in performance.

> ... and that's the gist of my question: It seems to me likely
> that the actual time to sort an ArrayList of large-ish N size will
> be less than the time to build a TreeMap (BTW, Martin probably
> meant TreeSet) of the same N items. Argument: The TreeSet expends
> effort in keeping itself always sorted all the time, while the
> ArrayList has the freedom to be disordered up until the end, and
> then to impose an ordering just once. The ArrayList is asked to
> present one sorted version of N items, while the TreeSet must
> offer sorted versions of 1,2,3,...,N items. If the intermediate
> orderings are not required, I don't see much reason to compute them.

I can follow you so far that TreeSort is likely a bit slower
than the ArrayList sort.

But I can not see any reason to expect a big difference.

It is fundamentally the same divide and conquer principle
applied.

Arne


Arne Vajhøj

unread,
Apr 2, 2013, 9:29:32 PM4/2/13
to
I do not have a problem with 'slightly'.

> Another factor to keep in mind is algorithmic performance if the data
> isn't actually uniformly random. If the input data is already sorted,
> the sort function will likely achieve its best possible performance,
> while the tree map will likely achieve its worst possible performance.
> Since sorted data tends to be more realistic in practice than true
> random, sorted lists actually have some things going for them. :-)

Also true.

Arne


Eric Sosman

unread,
Apr 2, 2013, 10:29:52 PM4/2/13
to
The original assertion is "it would be *best* [emphasis mine]
to use a TreeMap<String> [sic] rather than an ArrayList<String>".
I'm not claiming that the difference is "big," nor even that the
difference is "important" -- for reasonably-sized directories, at
any rate. What I'm questioning is "best."

Also, I dispute "fundamentally the same." There is, I think,
a "fundamental" difference between a scheme that makes a sorted
traversal possible once at the end of things and a scheme that
promises such a traversal at every single intermediate stage.
The latter, it seems to me, necessarily does more work because it
adheres to a guarantee at points 1,2,...,N instead of at N only.

--
Eric Sosman
eso...@comcast-dot-net.invalid

Robert Klemme

unread,
Apr 3, 2013, 2:09:30 AM4/3/13
to
On 02.04.2013 22:41, Eric Sosman wrote:
> On 4/2/2013 3:06 PM, Robert Klemme wrote:
>> [...]
>> I believe in using "final" pretty often as it will immediately indicate
>> which local variables are constant for a method call and which are
>> modified all the time. [...]
>
> De gustibus non disputandum est, but I think "final" should
> be reserved for things that *mustn't* change, and shouldn't just
> be pasted on to anything that happens to remain constant in the
> code's current incarnation. When considering a change to some
> code I might see
>
> Thing thing = getThing();
> // ... code that doesn't happen to change `thing'

I am so used to using "final" that this immediately makes me wonder why
it's not final - did the author intend to not change it, forget to
change it or forgot the "final"? :-)

> or I might see
>
> final Thing thing = getThing();
> // ... code that (obviously) doesn't change `thing'
>
> In the first case I might think about inserting, say,
>
> if (thing == null)
> thing = fallbackThing();
>
> ... while in the second case I wouldn't even consider it: I
> would suppose that the code relied on `thing' being exactly
> what getThing() had returned, perhaps in some way and for some
> reason not clear to me.
>
> But, as I said above, de gustibus.

Maybe we're not that far apart: I make things "final" that are not
supposed to change. If at a later time I decide they need to change I
remove the "final" but it reminds me that other code relies on this
value not changing - so I can check whether the change breaks the code
in some way.

>> Generally I find "finally" quite useful - apparently significantly more
>> useful than you do. :-)
>
> "finally" is a Godsend -- but did you mean "final"?

Yes, of course.

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Arved Sandstrom

unread,
Apr 3, 2013, 4:45:46 AM4/3/13
to
On 04/02/2013 09:04 PM, Joerg Meier wrote:
> On Tue, 2 Apr 2013 22:52:20 +0000 (UTC), Martin Gregorie wrote:
>
>> On Tue, 02 Apr 2013 18:22:55 -0400, Eric Sosman wrote:
>>> On 4/2/2013 5:06 PM, Martin Gregorie wrote:
>>>> [...]
>>>> Its also not clear to me whether the OP is expecting some form of
>>>> sorted list of filenames. If he is expecting that, it would be best to
>>>> use a TreeMap<String> rather than an ArrayList<String> to store the
>>>> filenames.
>>> Is there a reason to prefer TreeMap (or other SortedMap) over
>>> accumulate-disordered-and-sort-afterward?
>> I think so, yes, because none of File's list() and listFiles() methods
>> guarantee the order of the returned files. By using TreeMap or equivalent
>> the OP gets the sort for free, should it be required.
>
> For free ? The cost is just distributed amongst the insert calls, and is
> likely considerably higher than with an unsorted list that has a single
> sort call once it is filled. SortedMaps are for things that need sorting
> accessible before all elements are inserted, which really isn't the case
> here.
>
>> I use it a lot, both for that and because accessing stored objects by key
>> from a TreeMap is almost certainly faster than scanning an ArrayMap
>> unless it contains very few objects indeed.
>
> Java doesn't have ArrayMaps.

[SNIP]

Well, Java actually does have ArrayMaps, if one is willing to include
published APIs other than those of the JDK. MyFaces, and Google API Java
Client, and Oracle Fusion Middleware Java API have similar ones, and
from the Javadocs (they all essentially boil down to "good for small
number of entries") they even resemble Martin's description.

AHS

subhaba...@gmail.com

unread,
Apr 3, 2013, 4:47:28 AM4/3/13
to
On Tuesday, April 2, 2013 3:41:53 PM UTC+5:30, subhaba...@gmail.com wrote:
> Dear Group,
>
>
>
> I am taking out the files in my desktop folder, as,
>
>
>
> File folder = new File("C:\\Users\\subhabrata\\Desktop");
>
>
>
> Next, I am trying to take them out one by one as using for loop and name
>
> of each file is converted to String,
>
>
>
> for( File name :folder.listFiles()){
>
> String s1=name.toString();
>
> System.out.println("####"+s1);
>
> System.out.print( name );
>
> }
>
>
>
> Till this there is no issue, now I am trying to insert name of all the files in an array, generally it can be done, as,
>
>
>
> ArrayList<String> myList = new ArrayList<String>();
>
> myList.add(s1);
>
>
>
> But the problem I am facing is, if I put it as,
>
>
>
> for( File name :folder.listFiles()){
>
> String s1=name.toString();
>
> System.out.println("####"+s1);
>
> System.out.print( name );
>
> ArrayList<String> myList = new ArrayList<String>();
>
> myList.add(s1);
>
> }
>
>
>
> I am getting name of files individually but I want to see them as the whole bunch like,
>
>
>
> myList=["string1","string2","string3",...."StringN"]
>
>
>
> My aim is to check the names then in another for loop and if match is not found with some defined name update the list.
>
>
>
> I am slightly new in Java so if anyone can kindly suggest how I should address it.
>
>
>
> Regards,
>
> Subhabrata.

Thanks Room for suggestion and discussion. It worked. Regards,Subhabrata.

Steven Simpson

unread,
Apr 3, 2013, 5:35:22 AM4/3/13
to
On 03/04/13 09:47, subhaba...@gmail.com wrote:
> It worked.

What worked? I counted a dozen or so distinct suggestions, not
necessarily mutually exclusive.

1. Build the combined string with a loop.
2. Use Guava libraries.
3. Use Apache libraries.
4. list.toString()
5. Move the list creation to before the loop.
6. Arrays.toString(list.toArray())
7. Don't bother trying to compose a string.
8. Create a fixed-size list using Arrays.asList.
9. Create a fully mutable list using new ArrayList(Arrays.asList)
10. Create a File object representing the filename you're looking for,
and test directly.
11. Use FastCat.
12. Use StringBuilder.
13. Use getPath().
14. Use getName().

lipska the kat

unread,
Apr 3, 2013, 6:15:47 AM4/3/13
to
On 02/04/13 20:06, Robert Klemme wrote:
> On 04/02/2013 04:08 PM, lipska the kat wrote:
>
>> Just as a matter of interest what's with all the finals
>>
>> particularly
>>
>> for (final File name : folder.listFiles())

[snip]

> I believe in using "final" pretty often as it will immediately indicate
> which local variables are constant for a method call and which are
> modified all the time. Plus, with "final" you can easier catch errors
> in control flow:
>
> final String x;
>
> if ( someCondition() ) {
> x = y.toString();
> }
> else {
> if ( someOtherCondition() ) {
> x = "foo";
> }
> // forgot the else branch here
> x = "bar";
> }
>
> System.out.println("We got " + x);
>
> Generally I find "finally" quite useful - apparently significantly more
> useful than you do. :-)

Well I'm not sure that using a storage class to help you write a
conditional statement is 'good programming style' but hey ho, different
strokes for different folks :-)

I know you mean final of course.
finally is the last recourse of the desperate :-)

Anyway, the usability of final depends on your point of view I suppose.

If for some reason I find myself using 'final' all over the place then I
would have to ask myself if my abstraction was coherent. If one has
something, or in fact a number of somethings that need 'protecting' in
this way then surely it is better to wrap them up in a component and
control access by virtue of the public interface of that component.

It's more OO, makes for cleaner code and of course provides opportunity
for the holy grail of OO 're-usability'

Joerg Meier

unread,
Apr 3, 2013, 9:26:34 AM4/3/13
to
On Wed, 03 Apr 2013 05:45:46 -0300, Arved Sandstrom wrote:

> On 04/02/2013 09:04 PM, Joerg Meier wrote:
>> Java doesn't have ArrayMaps.
> [SNIP]

> Well, Java actually does have ArrayMaps, if one is willing to include
> published APIs other than those of the JDK.

If one is willing to do that, the expression "Java has" or "Java doesn't
have" becomes effictively meaningless.

For example, would you consider the following statements to be true ?

Java has a 'val' data type.
Java has an OpenGL 3D engine.
Java has automatic getter and setter generation.
Java has voice recognition.
Java has function pointers.
Java has delegates.

I think most people would say those, as well as "Java has ArrayMaps", are
wrong. There is relatively little point to asking if a language the size
and popularity of Java has something 3rd party created.

In other words: no, when I say "Java doesn't have xxx", I don't count third
party libraries, and I have trouble believing most other people would.

Robert Klemme

unread,
Apr 3, 2013, 1:08:34 PM4/3/13
to
I am not sure what you mean by that. Can you elaborate? Where's the
storage class in the example above?

> Anyway, the usability of final depends on your point of view I suppose.

We can certainly agree on *that*.

> If for some reason I find myself using 'final' all over the place then I
> would have to ask myself if my abstraction was coherent. If one has
> something, or in fact a number of somethings that need 'protecting' in
> this way then surely it is better to wrap them up in a component and
> control access by virtue of the public interface of that component.

It probably depends. Sometimes you want to hold on to something because
obtaining it is expensive or the accessor might return a changed version
during subsequent calls but you want to be sure to retain a specific
status. In those cases I would not think that wrapping it up
necessarily helps because the data may actually have been wrapped
already. It feels a bit over the top introducing another layer just to
avoid a local variable with "final".

> It's more OO, makes for cleaner code and of course provides opportunity
> for the holy grail of OO 're-usability'

Maybe I could better see (and agree) if you provide a specific example
of what you mean here.

lipska the kat

unread,
Apr 3, 2013, 2:51:05 PM4/3/13
to
final, although it's not is it, at least it's not Java terminology,
apologies, I should have said 'modifier'. I'll restate.

Well I'm not sure that using a modifier to help you write a
conditional statement is 'good programming style'. When I see the
modifier final it says something to me, it says, this value is not
modifiable ('scuse the pun). Is it improving the clarity of your code to
use final for it's side effect, that is the side effect of causing the
compiler to barf because a final variable may already have been
initialized. I'm not sure about that.

>> Anyway, the usability of final depends on your point of view I suppose.
>
> We can certainly agree on *that*.
>
>> If for some reason I find myself using 'final' all over the place then I
>> would have to ask myself if my abstraction was coherent. If one has
>> something, or in fact a number of somethings that need 'protecting' in
>> this way then surely it is better to wrap them up in a component and
>> control access by virtue of the public interface of that component.
>
> It probably depends. Sometimes you want to hold on to something because
> obtaining it is expensive or the accessor might return a changed version
> during subsequent calls but you want to be sure to retain a specific
> status. In those cases I would not think that wrapping it up
> necessarily helps because the data may actually have been wrapped
> already. It feels a bit over the top introducing another layer just to
> avoid a local variable with "final".

For a single local variable I'd probably agree, in fact in general I
would agree but that wasn't my initial point really, in the code that
kicked off this sub thread there was more than one final variable, in
fact there were several in close proximity, I was initially questioning
the clarity of this for a new user. However then I opened my mouth and
put my foot in it and said ...

>> It's more OO, makes for cleaner code and of course provides opportunity
>> for the holy grail of OO 're-usability'
>
> Maybe I could better see (and agree) if you provide a specific example
> of what you mean here.

I think you probably know what I mean and any off the cuff example will
be contrived to the point irrelevance, so, leave it with me and I'll see
if I can come up with a simple self contained example.

Joerg Meier

unread,
Apr 3, 2013, 3:01:18 PM4/3/13
to
On Wed, 03 Apr 2013 19:51:05 +0100, lipska the kat wrote:

> [...] When I see the
> modifier final it says something to me, it says, this value is not
> modifiable ('scuse the pun).

Then you need to read a Java beginner tutorial ;)

"final" makes a variable or field impossible to reassign. It says
absolutely nothing at all about whether or not that variables is
modifiable. What you are thinking of is immutability, something that is not
formalized in Java. In Java, having final mutable fields is perfectly
legitimate.

I know you know that, of course, I'm just saying, that's not really a
sensible way to look at final imo.

Robert Klemme

unread,
Apr 3, 2013, 5:05:57 PM4/3/13
to
On 03.04.2013 20:51, lipska the kat wrote:
> On 03/04/13 18:08, Robert Klemme wrote:

>> I am not sure what you mean by that. Can you elaborate? Where's the
>> storage class in the example above?
>
> final, although it's not is it, at least it's not Java terminology,
> apologies, I should have said 'modifier'. I'll restate.

Ah, OK, I see. Thanks!

> Well I'm not sure that using a modifier to help you write a
> conditional statement is 'good programming style'. When I see the
> modifier final it says something to me, it says, this value is not
> modifiable ('scuse the pun).

Sometimes you need nested conditions as shown and with a blank final you
can ensure that the variable is assigned exactly once on every possible
path. I find that useful.

> Is it improving the clarity of your code to
> use final for it's side effect, that is the side effect of causing the
> compiler to barf because a final variable may already have been
> initialized. I'm not sure about that.

That's not a side effect - it is _the_ effect of "final" modifier for
variables. "final" ensures a variable is assigned to at most once:

http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4

There is no other effect - final is all about assignment. This is true
for local variables - it's different with field which get assigned
compile time constants.

I'd say, "final" is probably even more useful for fields because it
ensures that a field is initialized in every constructor path - you
cannot forget it.

http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.2

> For a single local variable I'd probably agree, in fact in general I
> would agree but that wasn't my initial point really, in the code that
> kicked off this sub thread there was more than one final variable, in
> fact there were several in close proximity, I was initially questioning
> the clarity of this for a new user. However then I opened my mouth and
> put my foot in it and said ...

:-)

>> Maybe I could better see (and agree) if you provide a specific example
>> of what you mean here.
>
> I think you probably know what I mean and any off the cuff example will
> be contrived to the point irrelevance, so, leave it with me and I'll see
> if I can come up with a simple self contained example.

Thank you!

Arved Sandstrom

unread,
Apr 3, 2013, 5:09:36 PM4/3/13
to
If we're going to be pedantic I might as well add that I wouldn't myself
say that Java has ArrayLists or HashMaps either. I consider "Java" to be
the language. If we're going to talk official libraries you'd have to
refer to a specific version of J2SE/Java SE or J2EE/Java EE, for example.

Having said that, I think the pragmatic question would be (or would have
been), are there reliable libraries available for a Java programmer to
do X? In many cases, both now and historically, if one were to adopt
your narrower definition, one would have to admit that X cannot be
easily done with just the Java language and official platform
APIs/implementations, not without a great deal of coding, whereas in
reality people would be availing themselves of well-known 3rd party
libraries to do just that.

AHS

markspace

unread,
Apr 3, 2013, 5:15:56 PM4/3/13
to
On 4/3/2013 12:01 PM, Joerg Meier wrote:

> "final" makes a variable or field impossible to reassign. It says
> absolutely nothing at all about whether or not that variables is
> modifiable. What you are thinking of is immutability, something that is not
> formalized in Java.

Well, immutability is formalized in the JLS, and it's pretty important:

"final fields also allow programmers to implement thread-safe immutable
objects without synchronization." etc.

<http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5>

You might be referring to something else, but what you wrote there is
kind of misleading, at least.


Arne Vajhøj

unread,
Apr 3, 2013, 6:22:42 PM4/3/13
to
????

The text you quote do not define immutable neither formal nor informal.

It refer to the concept.

If immutable is defined formally somewhere in the JLS it must be
somewhere else.

Until we have a ref, then I can't see anything misleading.

Arne



Martin Gregorie

unread,
Apr 3, 2013, 6:37:35 PM4/3/13
to
On Tue, 02 Apr 2013 21:08:26 -0400, Eric Sosman wrote:

> On 4/2/2013 6:52 PM, Martin Gregorie wrote:
>> On Tue, 02 Apr 2013 18:22:55 -0400, Eric Sosman wrote:
>>
>>> On 4/2/2013 5:06 PM, Martin Gregorie wrote:
>>>> [...]
>>>> Its also not clear to me whether the OP is expecting some form of
>>>> sorted list of filenames. If he is expecting that, it would be best
>>>> to use a TreeMap<String> rather than an ArrayList<String> to store
>>>> the filenames.
>>>
>>> Is there a reason to prefer TreeMap (or other SortedMap) over
>>> accumulate-disordered-and-sort-afterward?
>>>
>> I think so, yes, because none of File's list() and listFiles() methods
>> guarantee the order of the returned files. By using TreeMap or
>> equivalent the OP gets the sort for free, should it be required.
>
> "For free" seems to have swept a few coins under the rug.
> The sort is by no means "free," since computational effort is expended
> in producing it.
>
Sure, it may be more expensive from the computational aspect, but its
free functionality from the coder's viewpoint.

> My question is why one should prefer
> keep-it-always-sorted-even-during-the-accumulation-phase over
> just-let-the-chips-fall-and-sort-them-later. It seems to me the latter
> is likely to be cheaper in both time and memory, and that the one extra
> line of code ("Collections.sort(list)") is not an overwhelming burden on
> the programmer.
>
I think rather that its computationally expensive if its holding a fairly
small collection of objects that is undergoing fast turnover and little
or no keyed retrieval or updating.

As soon as the volume gets very large the usual red-black binary tree
becomes rather cheap in terms of keyed access (a miss - the worst case -
needs only 24 key comparisons to search a collection of 16 million items)
and maintaining the ordered collection and/or updating it shares the same
low cost for large collections - and additionally you never need to sort
it.


>> I use it a lot, both for that and because accessing stored objects by
>> key from a TreeMap is almost certainly faster than scanning an ArrayMap
>> unless it contains very few objects indeed.
>
> Sorry: "ArrayMap"?
>
I meant ArrayList - my bad.

markspace

unread,
Apr 3, 2013, 6:41:24 PM4/3/13
to
On 4/3/2013 3:22 PM, Arne Vajh�j wrote:

> The text you quote do not define immutable neither formal nor informal.
>
> It refer to the concept.
>
> If immutable is defined formally somewhere in the JLS it must be
> somewhere else.
>
> Until we have a ref, then I can't see anything misleading.


Are you serious, Arne? Did you read the section I linked to? I didn't
quote the whole thing, it would be immense. I just quoted one line to
show that the section did talk about immutability, not to definitively
establish all the ins-and-outs of immutability in the JLS. There's no
point in me copying what you can read yourself.

Honestly I'm shocked at your response and I think you're missing the
point by a wide margin. Are you trying to tell me that final fields are
not involved in immutability in Java?


Martin Gregorie

unread,
Apr 3, 2013, 6:43:51 PM4/3/13
to
On Wed, 03 Apr 2013 02:04:19 +0200, Joerg Meier wrote:

> On Tue, 2 Apr 2013 22:52:20 +0000 (UTC), Martin Gregorie wrote:
>
>> On Tue, 02 Apr 2013 18:22:55 -0400, Eric Sosman wrote:
>>> On 4/2/2013 5:06 PM, Martin Gregorie wrote:
>>>>[...]
>>>> Its also not clear to me whether the OP is expecting some form of
>>>> sorted list of filenames. If he is expecting that, it would be best
>>>> to use a TreeMap<String> rather than an ArrayList<String> to store
>>>> the filenames.
>>> Is there a reason to prefer TreeMap (or other SortedMap) over
>>> accumulate-disordered-and-sort-afterward?
>> I think so, yes, because none of File's list() and listFiles() methods
>> guarantee the order of the returned files. By using TreeMap or
>> equivalent the OP gets the sort for free, should it be required.
>
> For free ?
>
I meant in terms of coding effort.

> The cost is just distributed amongst the insert calls, and is
> likely considerably higher than with an unsorted list that has a single
> sort call once it is filled.
>
Not necessarily so (see above) and that's why I specified a TreeMap
rather than any other type of ordered map because of the relative drop in
access costs as the collection size increases.

> SortedMaps are for things that need sorting
> accessible before all elements are inserted
>
And isn't the case with the TreeMap either - red-black binary trees have
rather nice characteristics there.

> Java doesn't have ArrayMaps.
>
Yeah, I meant ArrayList and should have been obvious from the context
provided by the OP.

Joerg Meier

unread,
Apr 3, 2013, 6:46:53 PM4/3/13
to
You display an honestly shocking and disturbing misunderstanding here. I
can only assume that this is some sort of temporary brain fart on your part
or bad communication between us. Making an object reference final does not
make the object immutable, and I have trouble believing you really think so
yourself.

Think about this piece of code:

final Point p = new Point(0, 0);
p.move(1, 1);

Are you really trying to say that you believe that the final keyword has
made p immutable, and that the call to p.move will fail to mut..ate ? p,
and that a subsequent call to p.getX() will return 0 ? Because if yes, then
you are simply wrong, and if no, then p is not immutable.

What the above quote means (and says) is that by USING final in the MAKING
of an object (as in writing a class), you can make an immutable object:

public class A {
final int b = 123;
}

A a = new A(); will now produce an immutable object a.

In fact it is a very popular (if not the most popular) way to deal with
synchronization to simply make as much as you can immutable, as that frees
you of a majority of synchronization concerns and issues.

But of course, again, you cannot make an mutable OBJECT immutable simply by
creating a reference to it that is decorated with final.

Basically, it's an issue about outside or inside: using final inside an
object on its fields can make that object immutable (assuming all state is
covered with finals), but just because you have a final reference to an
object does not change whether the object is modifiable or not.

Again, I'm pretty certain that you already know all of the above and we are
just having a communication breakdown.

Joerg Meier

unread,
Apr 3, 2013, 6:54:59 PM4/3/13
to
On Wed, 03 Apr 2013 18:09:36 -0300, Arved Sandstrom wrote:

> If we're going to be pedantic I might as well add that I wouldn't myself
> say that Java has ArrayLists or HashMaps either. I consider "Java" to be
> the language. If we're going to talk official libraries you'd have to
> refer to a specific version of J2SE/Java SE or J2EE/Java EE, for example.

You can feel free to say whatever you want, but lets be realistic: the
majority of people will say "Java has" for stuff in the JCL, and "Java
doesn't have" for stuff not in the JCL. And I am 99% certain that if I had
asked you any of the examples above, you would have said "No, Java doesn't
have a val data type", and you would have says "Yes, Java has a hash map,
it's java.util.HashMap".

You can be pedantic all you want, but I would argue that "stuff in the JCL"
is the definition used by the vast majority of people and really the only
one that makes much sense.

> Having said that, I think the pragmatic question would be (or would have
> been), are there reliable libraries available for a Java programmer to
> do X? In many cases, both now and historically, if one were to adopt
> your narrower definition, one would have to admit that X cannot be
> easily done with just the Java language and official platform
> APIs/implementations, not without a great deal of coding, whereas in
> reality people would be availing themselves of well-known 3rd party
> libraries to do just that.

If one was asking about libraries, one would likely ask that, and not
whether Java has it. I can only repeat what I said above.

Joerg Meier

unread,
Apr 3, 2013, 7:08:15 PM4/3/13
to
On Wed, 3 Apr 2013 22:43:51 +0000 (UTC), Martin Gregorie wrote:

> On Wed, 03 Apr 2013 02:04:19 +0200, Joerg Meier wrote:
>> On Tue, 2 Apr 2013 22:52:20 +0000 (UTC), Martin Gregorie wrote:
>>> On Tue, 02 Apr 2013 18:22:55 -0400, Eric Sosman wrote:
>>>> On 4/2/2013 5:06 PM, Martin Gregorie wrote:
>>>>>[...]
>>>>> Its also not clear to me whether the OP is expecting some form of
>>>>> sorted list of filenames. If he is expecting that, it would be best
>>>>> to use a TreeMap<String> rather than an ArrayList<String> to store
>>>>> the filenames.
>>>> Is there a reason to prefer TreeMap (or other SortedMap) over
>>>> accumulate-disordered-and-sort-afterward?
>>> I think so, yes, because none of File's list() and listFiles() methods
>>> guarantee the order of the returned files. By using TreeMap or
>>> equivalent the OP gets the sort for free, should it be required.
>> For free ?
> I meant in terms of coding effort.

In terms of coding effort, it's one single line.

>> The cost is just distributed amongst the insert calls, and is
>> likely considerably higher than with an unsorted list that has a single
>> sort call once it is filled.
> Not necessarily so (see above) and that's why I specified a TreeMap
> rather than any other type of ordered map because of the relative drop in
> access costs as the collection size increases.

A TreeMap has a higher access cost than an ArrayList. It's O(log(n)) for
both get and put, whereas ArrayList's is O(1).

>> SortedMaps are for things that need sorting
>> accessible before all elements are inserted
> And isn't the case with the TreeMap either - red-black binary trees have
> rather nice characteristics there.

Which are nevertheless still only in the best case scenario as good as the
alternative, and never better.

>> Java doesn't have ArrayMaps.
> Yeah, I meant ArrayList and should have been obvious from the context
> provided by the OP.

Not really. Since you want access by key, it makes no sense to use an
ArrayList at all. But I suppose your original point, then, was correct: a
TreeMap would indeed be superiour to storing logical map data in an
ArrayList - I'm not even sure how you would fit both key and value into an
ArrayList. Was your alternative to using a Map to make a patchwork Entry
class to put keys and values in, and then make an ArrayList of those ?

Because if it was, I can think of plenty more scenarios that would be worse
than storing things in a TreeMap. Storing them in a String, for example.
But just because Strings suck to store map data in doesn't mean everyone
who wants to store map data should therefore use a TreeMap.

markspace

unread,
Apr 3, 2013, 7:10:46 PM4/3/13
to
On 4/3/2013 3:46 PM, Joerg Meier wrote:

> final Point p = new Point(0, 0);
> p.move(1, 1);
>
> Are you really trying to say that you believe that the final keyword has
> made p immutable,

Nope, p is clearly mutable here.

> public class A {
> final int b = 123;
> }

OK, as far as it goes. But see below.

> But of course, again, you cannot make an mutable OBJECT immutable simply by
> creating a reference to it that is decorated with final.

Yup, you can. This class is also immutable:

public class Stooges {
private final ArrayList<String> stooges = new ArrayList<>(3);
{ stooges.add("Larry"); stooges.add("Curly"); stooges.add("Moe");}

public String getStooge( int stooge ) {
if( stooge < 1 || stooge > 3 ) throw new IllegalArgumentException();
return stooges.get( stooge-1 );
}
}

Now as long as I haven't made some syntax or other simple error, all
instances of Stooges are immutable under the section of the JLS I
quoted. More over, each one is thread safe in all circumstances and
does not need synchronization to make it thread safe.

You may know this yourself, but the way you wrote the bit I quoted made
is sound like final fields have no special semantics associated with
them with respect to immutable objects (like the stooges ArrayList I
used above), when in fact they do. Although not in the fashion you
implied with p above, of course.

> Again, I'm pretty certain that you already know all of the above and we are
> just having a communication breakdown.

I think so.


Joerg Meier

unread,
Apr 3, 2013, 7:25:37 PM4/3/13
to
On Wed, 03 Apr 2013 16:10:46 -0700, markspace wrote:

> On 4/3/2013 3:46 PM, Joerg Meier wrote:
>> But of course, again, you cannot make an mutable OBJECT immutable simply by
>> creating a reference to it that is decorated with final.
> Yup, you can. This class is also immutable:

> public class Stooges {
> private final ArrayList<String> stooges = new ArrayList<>(3);
> { stooges.add("Larry"); stooges.add("Curly"); stooges.add("Moe");}
>
> public String getStooge( int stooge ) {
> if( stooge < 1 || stooge > 3 ) throw new IllegalArgumentException();
> return stooges.get( stooge-1 );
> }
> }

But it's immutable because you don't expose mutable functionality, not
because of the final keyword. Let me make a small alteration that will make
your class mutable, without removing the final keyword:

public class Stooges {
private final ArrayList<String> stooges = new ArrayList<>(3);
{ stooges.add("Larry"); stooges.add("Curly"); stooges.add("Moe");}

public String getStooge( int stooge ) {
if( stooge < 1 || stooge > 3 ) throw new IllegalArgumentException();
return stooges.get( stooge-1 );
}

public ArrayList<String> getStooges() {
return stooges;
}
}

There, and suddenly it's mutable.

> Now as long as I haven't made some syntax or other simple error, all
> instances of Stooges are immutable under the section of the JLS I
> quoted. More over, each one is thread safe in all circumstances and
> does not need synchronization to make it thread safe.

Yours would be immutable with or without the final keyword. It's kind of a
bad example, because ArrayList itself is mutable. Should have wrapped it in
Collections.unmodifiableList at least, but of course then it could still
have mutable contents (although of course not in the example, as String is
both immutable and final).

> You may know this yourself, but the way you wrote the bit I quoted made
> is sound like final fields have no special semantics associated with
> them with respect to immutable objects (like the stooges ArrayList I
> used above), when in fact they do. Although not in the fashion you
> implied with p above, of course.

final can be used to create a class that is immutable, but so can other
Java mechanics (such as private fields with no setter). While final
certainly lends itself to design of immutable classes, there really aren't
any special semantics associated with it any more than with the private
keyword.

>> Again, I'm pretty certain that you already know all of the above and we are
>> just having a communication breakdown.
> I think so.

Yeah, I figured halfway into my post that perceived misconception on your
part was too severe for it to actually be one. Nevertheless it seems a
worthwhile topic to discuss and maybe it will help someone else reading it
understand things better.

Arved Sandstrom

unread,
Apr 3, 2013, 7:30:53 PM4/3/13
to
On 04/03/2013 07:54 PM, Joerg Meier wrote:
> On Wed, 03 Apr 2013 18:09:36 -0300, Arved Sandstrom wrote:
>
>> If we're going to be pedantic I might as well add that I wouldn't myself
>> say that Java has ArrayLists or HashMaps either. I consider "Java" to be
>> the language. If we're going to talk official libraries you'd have to
>> refer to a specific version of J2SE/Java SE or J2EE/Java EE, for example.
>
> You can feel free to say whatever you want, but lets be realistic: the
> majority of people will say "Java has" for stuff in the JCL, and "Java
> doesn't have" for stuff not in the JCL. And I am 99% certain that if I had
> asked you any of the examples above, you would have said "No, Java doesn't
> have a val data type", and you would have says "Yes, Java has a hash map,
> it's java.util.HashMap".
>
> You can be pedantic all you want, but I would argue that "stuff in the JCL"
> is the definition used by the vast majority of people and really the only
> one that makes much sense.
[ SNIP ]

I'm probably not most people. I can do very little of my professional
Java work using just the Java language and only official Java platform
libraries. So I value 3rd party offerings very highly.

As for the questions, what are Java primitives if not value types? And I
very likely wouldn't say that Java has a hash map, honestly; it's too
ingrained in me that "Java" is the language only. I think similarly with
every other language + platform I can think of: C# is a .NET language,
the .NET framework is actually what supplies the libraries. Haskell is a
language, GHC and other environments supply many libraries. Etc.

But I'll concede that I'm not the vast majority of people. A lot of
people in that vast majority have also been often wrong when they
conflate an API supplied by the Java platform and an implementation
thereof, and happily believe that "Java" is providing all of it.

AHS

Joerg Meier

unread,
Apr 3, 2013, 7:35:21 PM4/3/13
to
On Wed, 03 Apr 2013 20:30:53 -0300, Arved Sandstrom wrote:

> On 04/03/2013 07:54 PM, Joerg Meier wrote:
>> On Wed, 03 Apr 2013 18:09:36 -0300, Arved Sandstrom wrote:
>>> If we're going to be pedantic I might as well add that I wouldn't myself
>>> say that Java has ArrayLists or HashMaps either. I consider "Java" to be
>>> the language. If we're going to talk official libraries you'd have to
>>> refer to a specific version of J2SE/Java SE or J2EE/Java EE, for example.
>> You can feel free to say whatever you want, but lets be realistic: the
>> majority of people will say "Java has" for stuff in the JCL, and "Java
>> doesn't have" for stuff not in the JCL. And I am 99% certain that if I had
>> asked you any of the examples above, you would have said "No, Java doesn't
>> have a val data type", and you would have says "Yes, Java has a hash map,
>> it's java.util.HashMap".

>> You can be pedantic all you want, but I would argue that "stuff in the JCL"
>> is the definition used by the vast majority of people and really the only
>> one that makes much sense.
> [ SNIP ]

> I'm probably not most people. I can do very little of my professional
> Java work using just the Java language and only official Java platform
> libraries. So I value 3rd party offerings very highly.

Using a lot of JavaEE, I'm right there with you. But I wouldn't say
RestEASY or Jackson are part of Java any more than I would say Firefox is
part of Windows.

> As for the questions, what are Java primitives if not value types? And I

val data types != value types, a val type is a variable type that can be
used like:

for (val file : fileList) { ... // val is of type File here }

Basically an inferred type.

> very likely wouldn't say that Java has a hash map, honestly; it's too
> ingrained in me that "Java" is the language only. I think similarly with

So you would say that Java has ArrayMap, but not a hash map. You need to
pick one side to disagree with me on, it seems ;-)

markspace

unread,
Apr 3, 2013, 7:44:45 PM4/3/13
to
On 4/3/2013 4:25 PM, Joerg Meier wrote:

> Yours would be immutable with or without the final keyword.

No no no. This is my point. The final keyword has special semantics
associated with it in that particular case. It works a bit like the
volatile keyword: all writes to that point are made visible. In the
case of a private final field, the writes are made visible to ALL
THREADS in the system. THAT is what makes instances of the class
Stooges immutable.

That's why no synchronization is needed. Which is huge, conceptually.
I'll stop there because I think this may be the whole point of
misunderstanding here.







Arne Vajhøj

unread,
Apr 3, 2013, 7:49:41 PM4/3/13
to
On 4/3/2013 7:30 PM, Arved Sandstrom wrote:
> On 04/03/2013 07:54 PM, Joerg Meier wrote:
>> On Wed, 03 Apr 2013 18:09:36 -0300, Arved Sandstrom wrote:
>>
>>> If we're going to be pedantic I might as well add that I wouldn't myself
>>> say that Java has ArrayLists or HashMaps either. I consider "Java" to be
>>> the language. If we're going to talk official libraries you'd have to
>>> refer to a specific version of J2SE/Java SE or J2EE/Java EE, for
>>> example.
>>
>> You can feel free to say whatever you want, but lets be realistic: the
>> majority of people will say "Java has" for stuff in the JCL, and "Java
>> doesn't have" for stuff not in the JCL. And I am 99% certain that if I
>> had
>> asked you any of the examples above, you would have said "No, Java
>> doesn't
>> have a val data type", and you would have says "Yes, Java has a hash map,
>> it's java.util.HashMap".
>>
>> You can be pedantic all you want, but I would argue that "stuff in the
>> JCL"
>> is the definition used by the vast majority of people and really the only
>> one that makes much sense.
> [ SNIP ]
>
> I'm probably not most people. I can do very little of my professional
> Java work using just the Java language and only official Java platform
> libraries. So I value 3rd party offerings very highly.

I guess most do, but that does not make anything part of Java.

> As for the questions, what are Java primitives if not value types? And I
> very likely wouldn't say that Java has a hash map, honestly; it's too
> ingrained in me that "Java" is the language only. I think similarly with
> every other language + platform I can think of: C# is a .NET language,
> the .NET framework is actually what supplies the libraries. Haskell is a
> language, GHC and other environments supply many libraries. Etc.
>
> But I'll concede that I'm not the vast majority of people. A lot of
> people in that vast majority have also been often wrong when they
> conflate an API supplied by the Java platform and an implementation
> thereof, and happily believe that "Java" is providing all of it.

I believe there are precedence for that the owner of the
Java trademark may sue someone using the name Java for something
not having all the classes in the Java library (SUN vs MS).

So I would say that:

Java = Java language + Java library + JVM

Arne


Arved Sandstrom

unread,
Apr 3, 2013, 7:55:40 PM4/3/13
to
OK, I misconstrued your use of the term "val". Sure, like "var" and
"val" in various languages. Yes, we don't have that in Java.

>> very likely wouldn't say that Java has a hash map, honestly; it's too
>> ingrained in me that "Java" is the language only. I think similarly with
>
> So you would say that Java has ArrayMap, but not a hash map. You need to
> pick one side to disagree with me on, it seems ;-)
>
> Liebe Gruesse,
> Joerg
>
I used the term "Java" initially because I do recognize that most folks
use it exactly the way you say, even though I don't. But you'll recall
that very quickly after I made my distinction.

So truthfully I'd have to say that Java has neither, not by my usage.

I don't actually beat people up over this, you know. :-) It doesn't
exactly usually come up, someone just asks does anyone know a class or
classes that does such and such, and someone else suggests a library. If
it's 3rd party they'll say so, otherwise they just usually say it's
package such-and-such.

AHS

Arne Vajhøj

unread,
Apr 3, 2013, 7:56:01 PM4/3/13
to
On 4/3/2013 6:41 PM, markspace wrote:
> On 4/3/2013 3:22 PM, Arne Vajh�j wrote:
>
>> The text you quote do not define immutable neither formal nor informal.
>>
>> It refer to the concept.
>>
>> If immutable is defined formally somewhere in the JLS it must be
>> somewhere else.
>>
>> Until we have a ref, then I can't see anything misleading.
>
>
> Are you serious, Arne?

Very.

> Did you read the section I linked to? I didn't
> quote the whole thing, it would be immense. I just quoted one line to
> show that the section did talk about immutability, not to definitively
> establish all the ins-and-outs of immutability in the JLS. There's no
> point in me copying what you can read yourself.

JLS referring to immutability is utterly irrelevant.

The question is whether JLS defines it.

Feel free to quote where it defines it.

Or stop making claims.

> Honestly I'm shocked at your response and I think you're missing the
> point by a wide margin. Are you trying to tell me that final fields are
> not involved in immutability in Java?

I was just pointing out that what you quoted from JLS did not
support your claim that JLS had a formal definition of immutability.

I find it a bit difficult to see why you think that implies
"final fields are not involved in immutability in Java".

Arne


Joerg Meier

unread,
Apr 3, 2013, 7:57:14 PM4/3/13
to
On Wed, 03 Apr 2013 16:44:45 -0700, markspace wrote:

> On 4/3/2013 4:25 PM, Joerg Meier wrote:
>> Yours would be immutable with or without the final keyword.
> No no no. This is my point. The final keyword has special semantics
> associated with it in that particular case. It works a bit like the
> volatile keyword: all writes to that point are made visible. In the
> case of a private final field, the writes are made visible to ALL
> THREADS in the system. THAT is what makes instances of the class
> Stooges immutable.

Now I'm to being confused by you. final prevents any writes other than the
initial one. That initial write is not synchronized to other threads. If
you let an object instance get out that isn't fully constructed, then you
will get the usual synchornization issues, final or not. Don't believe me ?

Guess what this will print out:

public class FinalTest {
public static class Test {
public final String bla;

public Test() {
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(200);
} catch (final InterruptedException e) {}
System.out.println(bla);
try {
Thread.sleep(1000);
} catch (final InterruptedException e) {}
System.out.println(bla);
}
}).start();
try {
Thread.sleep(1000);
} catch (final InterruptedException e) {}
bla = "1234";
}
}

public static void main(final String[] args) {
final Test test = new Test();
}
}

If I misunderstood, and you believe that structural changes to the
ArrayList would be visible to all threads, then you are still wrong, but
you're going to have to write this test case as I restrict myself to one
test case per post ;)

> That's why no synchronization is needed. Which is huge, conceptually.
> I'll stop there because I think this may be the whole point of
> misunderstanding here.

The mere use of final does not remove the need for synchronization. Nor
does the mere lack of it dictate a need. The reason synchronization is not
needed with proper immutability is an effect from what final does - because
it can only be assigned once, once it is you can then let everyone play
with it, because you dont NEED to worry about writes - there will be none.

markspace

unread,
Apr 3, 2013, 7:58:25 PM4/3/13
to
On 4/3/2013 4:56 PM, Arne Vajhøj wrote:
>
> I was just pointing out that what you quoted from JLS did not
> support your claim that JLS had a formal definition of immutability.
>

But I don't care if you believe. The link is for your sake.

> I find it a bit difficult to see why you think that implies
> "final fields are not involved in immutability in Java".

Er, I'm saying the opposite.


Joerg Meier

unread,
Apr 3, 2013, 8:00:59 PM4/3/13
to
On Wed, 03 Apr 2013 20:55:40 -0300, Arved Sandstrom wrote:

> On 04/03/2013 08:35 PM, Joerg Meier wrote:
>> On Wed, 03 Apr 2013 20:30:53 -0300, Arved Sandstrom wrote:
>>> As for the questions, what are Java primitives if not value types? And I
>> val data types != value types, a val type is a variable type that can be
>> used like:

>> for (val file : fileList) { ... // val is of type File here }

>> Basically an inferred type.
> OK, I misconstrued your use of the term "val". Sure, like "var" and
> "val" in various languages. Yes, we don't have that in Java.

Actually, we do - if you count third party libraries ;-)

> So truthfully I'd have to say that Java has neither, not by my usage.

Then we just use the term differently. I'm alright with that.

Arne Vajhøj

unread,
Apr 3, 2013, 8:05:06 PM4/3/13
to
On 4/3/2013 7:56 PM, Arne Vajhøj wrote:
> On 4/3/2013 6:41 PM, markspace wrote:
But now you raise the question, then final is only slightly
involved in immutability in Java.

If is neither sufficient nor necessary to make them
immutable.

Bloch recommends using final for immutables to:
- express intention
- work better with the Java memory model

Arne

Arne Vajhøj

unread,
Apr 3, 2013, 8:08:11 PM4/3/13
to
On 4/3/2013 7:58 PM, markspace wrote:
> On 4/3/2013 4:56 PM, Arne Vajhøj wrote:
>> I was just pointing out that what you quoted from JLS did not
>> support your claim that JLS had a formal definition of immutability.
>
> But I don't care if you believe. The link is for your sake.

So it is there but you just don't want to provide the quote yourself.

Do you think that sounds credible?

>> I find it a bit difficult to see why you think that implies
>> "final fields are not involved in immutability in Java".
>
> Er, I'm saying the opposite.

Yes. But you you seemed to imply that I meant it based
on the JLS thing.

Arne


Arne Vajhøj

unread,
Apr 3, 2013, 8:10:23 PM4/3/13
to
On 4/3/2013 7:44 PM, markspace wrote:
> On 4/3/2013 4:25 PM, Joerg Meier wrote:
>
>> Yours would be immutable with or without the final keyword.
>
> No no no. This is my point. The final keyword has special semantics
> associated with it in that particular case. It works a bit like the
> volatile keyword: all writes to that point are made visible. In the
> case of a private final field, the writes are made visible to ALL
> THREADS in the system. THAT is what makes instances of the class
> Stooges immutable.
>
> That's why no synchronization is needed. Which is huge, conceptually.

It can be very important in multithreaded context.

But it is not what makes a class immutable.

Arne


Arne Vajhøj

unread,
Apr 3, 2013, 8:13:48 PM4/3/13
to
On 4/3/2013 2:09 AM, Robert Klemme wrote:
> On 02.04.2013 22:41, Eric Sosman wrote:
>> On 4/2/2013 3:06 PM, Robert Klemme wrote:
>>> [...]
>>> I believe in using "final" pretty often as it will immediately indicate
>>> which local variables are constant for a method call and which are
>>> modified all the time. [...]
>>
>> De gustibus non disputandum est, but I think "final" should
>> be reserved for things that *mustn't* change, and shouldn't just
>> be pasted on to anything that happens to remain constant in the
>> code's current incarnation. When considering a change to some
>> code I might see
>>
>> Thing thing = getThing();
>> // ... code that doesn't happen to change `thing'
>
> I am so used to using "final" that this immediately makes me wonder why
> it's not final - did the author intend to not change it, forget to
> change it or forgot the "final"? :-)

Many years ago the fathers of Java designed it so that default was
var and the final modifier could change that.

They could have decide to make val default and have a nonfinal
modifier that could change that.

You are trying to code as if they had picked the second.

Arne


Arne Vajhøj

unread,
Apr 3, 2013, 8:16:12 PM4/3/13
to
On 4/2/2013 10:29 PM, Eric Sosman wrote:
> On 4/2/2013 9:26 PM, Arne Vajhøj wrote:
>> On 4/2/2013 9:03 PM, Eric Sosman wrote:
>>> On 4/2/2013 8:20 PM, Arne Vajhøj wrote:
>>>> On 4/2/2013 8:04 PM, Joerg Meier wrote:
>>>>> On Tue, 2 Apr 2013 22:52:20 +0000 (UTC), Martin Gregorie wrote:
>>>>>
>>>>>> On Tue, 02 Apr 2013 18:22:55 -0400, Eric Sosman wrote:
>>>>>>> On 4/2/2013 5:06 PM, Martin Gregorie wrote:
>>>>>>>> [...]
>>>>>>>> Its also not clear to me whether the OP is expecting some form of
>>>>>>>> sorted list of filenames. If he is expecting that, it would be
>>>>>>>> best to
>>>>>>>> use a TreeMap<String> rather than an ArrayList<String> to store the
>>>>>>>> filenames.
>>>>>>> Is there a reason to prefer TreeMap (or other SortedMap) over
>>>>>>> accumulate-disordered-and-sort-afterward?
>>>>>> I think so, yes, because none of File's list() and listFiles()
>>>>>> methods
>>>>>> guarantee the order of the returned files. By using TreeMap or
>>>>>> equivalent
>>>>>> the OP gets the sort for free, should it be required.
>>>>>
>>>>> For free ? The cost is just distributed amongst the insert calls,
>>>>> and is
>>>>> likely considerably higher than with an unsorted list that has a
>>>>> single
>>>>> sort call once it is filled.
>>>>
>>>> It is not that obvious to me that:
>>>>
>>>> n O(1) + 1 O(nlogn) is that much faster than n log(n)
>>>
>>> By design, O() obscures all the coefficients. If you were
>>> to say that n*log(n) and 9999999999999999999999999999*n*log(n)
>>> are both O(n*log(n)) you would be right -- but if you were to
>>> claim the former was not "that much faster" than the latter you
>>> would be wrong by a factor of 9999999999999999999999999999.
>>
>> Yes.
>>
>> But given same big-O I would expect some solid reasons for a
>> big difference in coefficients before I assume a big difference
>> in performance.
>>
>>> ... and that's the gist of my question: It seems to me likely
>>> that the actual time to sort an ArrayList of large-ish N size will
>>> be less than the time to build a TreeMap (BTW, Martin probably
>>> meant TreeSet) of the same N items. Argument: The TreeSet expends
>>> effort in keeping itself always sorted all the time, while the
>>> ArrayList has the freedom to be disordered up until the end, and
>>> then to impose an ordering just once. The ArrayList is asked to
>>> present one sorted version of N items, while the TreeSet must
>>> offer sorted versions of 1,2,3,...,N items. If the intermediate
>>> orderings are not required, I don't see much reason to compute them.
>>
>> I can follow you so far that TreeSort is likely a bit slower
>> than the ArrayList sort.
>>
>> But I can not see any reason to expect a big difference.
>>
>> It is fundamentally the same divide and conquer principle
>> applied.
>
> The original assertion is "it would be *best* [emphasis mine]
> to use a TreeMap<String> [sic] rather than an ArrayList<String>".
> I'm not claiming that the difference is "big," nor even that the
> difference is "important" -- for reasonably-sized directories, at
> any rate. What I'm questioning is "best."

But I did not comment on Martin's "best".

I commented on Joerg's "likely considerably higher".

Arne

markspace

unread,
Apr 3, 2013, 8:19:17 PM4/3/13
to
On 4/3/2013 4:57 PM, Joerg Meier wrote:

> That initial write is not synchronized to other threads.

Yes it is! (Not immediately synchronized, at the end of the ctor.)
Read the JLS, besides the part I quoted above:

<http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.1>

"Let o be an object, and c be a constructor for o in which a final field
f is written. A freeze action on final field f of o takes place when c
exits, either normally or abruptly....

Given a write w, a freeze f, an action a (that is not a read of a final
field), a read r1 of the final field frozen by f, and a read r2 such
that hb(w, f), hb(f, a), mc(a, r1), and dereferences(r1, r2), then when
determining which values can be seen by r2, we consider hb(w, r2). (This
happens-before ordering does not transitively close with other
happens-before orderings.) "

That's as clear as mud, but what it means is that objects referenced by
final fields, and all writes to those objects, are made visible at the
end of the object's ctor.

> If
> you let an object instance get out that isn't fully constructed, then you
> will get the usual synchornization issues, final or not. Don't believe me ?

This is true. If the final field object escapes from the enclosing
class, or any writes are made after the object is constructed, then both
immutability and thread-safety are broken.

> If I misunderstood, and you believe that structural changes to the
> ArrayList would be visible to all threads, then you are still wrong,

In the second example you gave where the reference to 'stooges' leaves
the enclosing class, it is definitely neither immutable nor thread-safe.

> The mere use of final does not remove the need for synchronization.

Yes it does! That was explicitly stated in the very short bit I quoted
at the beginning of this whole mess.

> Nor
> does the mere lack of it dictate a need.

No. 'final' is special here.

> The reason synchronization is not
> needed with proper immutability is an effect from what final does - because
> it can only be assigned once, once it is you can then let everyone play
> with it, because you dont NEED to worry about writes - there will be none.

No, you still need to, at a low level, insert a memory barrier to make
those writes visible. You'd need to use synchronization or a volatile
variable or some other synchronization in Java, or you could see a
partially constructed object. Just like any regular object that doesn't
use final or volatile fields.

Also, go read Java Concurrency in Practice by Brian Goetz. He covers
this in some detail (complete with Stooges example).

markspace

unread,
Apr 3, 2013, 8:21:20 PM4/3/13
to
On 4/3/2013 5:08 PM, Arne Vajh�j wrote:

> Yes. But you you seemed to imply that I meant it based
> on the JLS thing.

No, I was replying to Joerg.


markspace

unread,
Apr 3, 2013, 8:24:21 PM4/3/13
to
On 4/3/2013 5:05 PM, Arne Vajhøj wrote:
> But now you raise the question, then final is only slightly
> involved in immutability in Java.
>
> If is neither sufficient nor necessary to make them
> immutable.

final is necessary. It is not sufficient (you also have to not mutate
the object in question after the enclosing object's ctor exits). I'm
pretty sure the field must also be explicitly private. (Implicitly
might not be enough to satisfy what ever escape analysis the Java
compiler does.)

>
> Bloch recommends using final for immutables to:
> - express intention
> - work better with the Java memory model

Read Java Concurrency in Practice. That's what I'm referring too.

Arne Vajhøj

unread,
Apr 3, 2013, 8:27:17 PM4/3/13
to
On 4/3/2013 8:21 PM, markspace wrote:
> On 4/3/2013 5:08 PM, Arne Vajhøj wrote:
>
>> Yes. But you you seemed to imply that I meant it based
>> on the JLS thing.
>
> No, I was replying to Joerg.

Hmm.

You replied to a post by me and only quoted me.

A bit difficult to guess that you were actually replying to Joerg.

Arne


markspace

unread,
Apr 3, 2013, 8:29:35 PM4/3/13
to
On 4/3/2013 5:10 PM, Arne Vajhøj wrote:
>
> It can be very important in multithreaded context.
>
> But it is not what makes a class immutable.

OK, that's true. The section I linked to refers to such objects as
"thread safe immutable." It's both concepts in one package. Objects
that aren't thread safe aren't immutable, and objects that aren't
immutable aren't thread safe. I guess that's why the two go together.

final is required, but you also have to actually prevent any
modification to the object's state after it is constructed. It is a two
part process, that is true.

markspace

unread,
Apr 3, 2013, 8:34:50 PM4/3/13
to
On 4/3/2013 5:27 PM, Arne Vajhøj wrote:
> On 4/3/2013 8:21 PM, markspace wrote:
>> On 4/3/2013 5:08 PM, Arne Vajhøj wrote:
>>
>>> Yes. But you you seemed to imply that I meant it based
>>> on the JLS thing.
>>
>> No, I was replying to Joerg.
>
> Hmm.
>
> You replied to a post by me and only quoted me.

The first post I made was to Joerg:

On 4/3/2013 12:01 PM, Joerg Meier wrote:

> "final" makes a variable or field impossible to reassign. It says
> absolutely nothing at all about whether or not that variables is
> modifiable. What you are thinking of is immutability, something that
is not
> formalized in Java.


Then you replied to me, saying that the section of the JLS I linked to
"17.5 Final Field Semantics" doesn't define immutability in Java
formally or informally. Which is wrong, if you just scan that section
for uses of the word "immutable." So that's where I kind of lost it.

Martin Gregorie

unread,
Apr 3, 2013, 8:42:43 PM4/3/13
to
On Thu, 04 Apr 2013 01:08:15 +0200, Joerg Meier wrote:

> On Wed, 3 Apr 2013 22:43:51 +0000 (UTC), Martin Gregorie wrote:
>
>> On Wed, 03 Apr 2013 02:04:19 +0200, Joerg Meier wrote:
>>> On Tue, 2 Apr 2013 22:52:20 +0000 (UTC), Martin Gregorie wrote:
>>>> On Tue, 02 Apr 2013 18:22:55 -0400, Eric Sosman wrote:
>>>>> On 4/2/2013 5:06 PM, Martin Gregorie wrote:
>>>>>>[...]
>>>>>> Its also not clear to me whether the OP is expecting some form of
>>>>>> sorted list of filenames. If he is expecting that, it would be best
>>>>>> to use a TreeMap<String> rather than an ArrayList<String> to store
>>>>>> the filenames.
>>>>> Is there a reason to prefer TreeMap (or other SortedMap) over
>>>>> accumulate-disordered-and-sort-afterward?
>>>> I think so, yes, because none of File's list() and listFiles()
>>>> methods guarantee the order of the returned files. By using TreeMap
>>>> or equivalent the OP gets the sort for free, should it be required.
>>> For free ?
>> I meant in terms of coding effort.
>
> In terms of coding effort, it's one single line.
>
Fair enough - unless, of course a new coder tries to sort the ArrayList
rather than using one of the standard SortedMaps. I note that there are
only two and that, while ConcurrentSkipListMap is obviously faster than
TreeMap for insert/amend/delete operations it would seem to be much
slower at producing ordered lists.

> A TreeMap has a higher access cost than an ArrayList. It's O(log(n)) for
> both get and put, whereas ArrayList's is O(1).
>
For individual items that's true, but if the list is being updated, even
at a low rate, then ordered access will need to at least check for out of
order data before anything gets retrieved. Thats an overhead that any
structure that preserves order through updates doesn't have.

> Not really. Since you want access by key, it makes no sense to use an
> ArrayList at all.
>
Which is where I came in: the OP had said that he wanted to get a String
containing a list of filenames that he represented as

"filename1,filename2,filename3,...."

which at least suggests that the filenames should be ordered.

That is why I suggested that if that's what he wanted he should be using
a TreeMap rather than an ArrayList.

> a TreeMap would indeed be superiour to storing logical map data in an
> ArrayList - I'm not even sure how you would fit both key and value into
> an ArrayList. Was your alternative to using a Map to make a patchwork
> Entry class to put keys and values in, and then make an ArrayList of
> those ?
>
I didn't suggest any alternative and never intended to, but you can see
somebody throwing the list of filenames into an ArrayList and then
running a bubble sort against the array. Ugly, I know, and bubble sorts
are horridly inefficient, but there's very little code in one. More to
the point, this would be a very natural approach for anybody coming from
a high level language background, e.g. Python, Perl, C, BASIC, PL/1,
COBOL,... doing exactly this.

> Because if it was, I can think of plenty more scenarios that would be
> worse than storing things in a TreeMap. Storing them in a String, for
> example. But just because Strings suck to store map data in doesn't mean
> everyone who wants to store map data should therefore use a TreeMap.
>
Indeed.


--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |

Arne Vajhøj

unread,
Apr 3, 2013, 8:32:36 PM4/3/13
to
On 4/3/2013 8:24 PM, markspace wrote:
> On 4/3/2013 5:05 PM, Arne Vajhøj wrote:
>> But now you raise the question, then final is only slightly
>> involved in immutability in Java.
>>
>> If is neither sufficient nor necessary to make them
>> immutable.
>
> final is necessary.

No.

> It is not sufficient (you also have to not mutate
> the object in question after the enclosing object's ctor exits). I'm
> pretty sure the field must also be explicitly private. (Implicitly
> might not be enough to satisfy what ever escape analysis the Java
> compiler does.)
>
>>
>> Bloch recommends using final for immutables to:
>> - express intention
>> - work better with the Java memory model
>
> Read Java Concurrency in Practice. That's what I'm referring too.

My copy page 47 footnote 12 says:

"It is technically possible to have an immutable object without all
fields being final"

Is that missing in your copy?

Arne


Eric Sosman

unread,
Apr 3, 2013, 8:50:26 PM4/3/13
to
On 4/3/2013 6:37 PM, Martin Gregorie wrote:
> On Tue, 02 Apr 2013 21:08:26 -0400, Eric Sosman wrote:
>
>> On 4/2/2013 6:52 PM, Martin Gregorie wrote:
>>>[...]
>>> I use it a lot, both for that and because accessing stored objects by
>>> key from a TreeMap is almost certainly faster than scanning an ArrayMap
>>> unless it contains very few objects indeed.
>>
>> Sorry: "ArrayMap"?
>>
> I meant ArrayList - my bad.

Okay, I still don't understand: How does "accessing stored
objects by key" pertain to an ArrayList, or to any List? You
can hunt through a List to find an element equal to a search
object (or having some specified relation to it), but "by key?"
There's nothing in the List abstraction to distinguish "key"
from "value" from "haddocks' eyes:" Something's in the List or
it ain't, and that's all.

For my part, I think that if you want to list a directory's
content in some sorted order, the preferred approach is to form
a List of the contents, paying no attention to order, and then
sort it at the end. Spending extra time and memory computing
intermediate results that you won't use seems pointless. YMMV.

--
Eric Sosman
eso...@comcast-dot-net.invalid

Joerg Meier

unread,
Apr 3, 2013, 8:53:10 PM4/3/13
to
On Wed, 03 Apr 2013 17:29:35 -0700, markspace wrote:

> On 4/3/2013 5:10 PM, Arne Vajhøj wrote:
>> It can be very important in multithreaded context.

>> But it is not what makes a class immutable.
> OK, that's true. The section I linked to refers to such objects as
> "thread safe immutable." It's both concepts in one package. Objects
> that aren't thread safe aren't immutable, and objects that aren't
> immutable aren't thread safe. I guess that's why the two go together.

I don't have time to answer your other, longer post before I have to leave,
but this one I wanted to interject on before I alt-f4 for the day: while
immutable objects are of course thread safe (due to there not being
anything that can be done to them that needs synchronization), of course
you can make thread safe objects that are mutable.

I don't even know what you were thinking when you wrote that. What do you
think locks and the synchronized keyword are for ? Immutable objects don't
need them.

> final is required, but you also have to actually prevent any
> modification to the object's state after it is constructed. It is a two
> part process, that is true.

Again: you can make immutable objects without final perfectly fine. It is
absolutely not required.

Eric Sosman

unread,
Apr 3, 2013, 9:20:29 PM4/3/13
to
I'm with Arne. The cited section uses the word "immutable"
and "immutability" without defining either. All it says is that
"final" can be an aid to implementing immutable objects -- but it
never says what "immutable" is. It doesn't even say that "final"
confers immutability; on the contrary, it says "final fields must
be *used correctly* [emphasis mine] to provide a guarantee of
immutability."

Toward the end of the section, we're told that String is
"perceived as truly immutable." So now there are two more notions:
"truly immutable" as opposed to merely "immutable," and "perceived
as truly immutable" as opposed to "actually truly immutable, not
dependent on somebody's perception." Where does the JLS define how
these three different kinds of immutability differ? Where does it
*define* even one of them?

Thought experiment: Using the JLS' definition of immutability,
support or refute "java.lang.String is mutable, because it computes
its hashCode() lazily and caches it in a non-final field, thereby
changing the String object's state at the first hashCode() call."

Thought experiment: Using the JLS' definition of immutability,
support or refute "All Java objects are mutable, because all have a
monitor whose state changes every time a synchronized block is
entered or exited. The monitor's state affects the behavior of
all threads attempting to synchronize on the object, so the change
of state is not strictly internal but is visible to all observers."

--
Eric Sosman
eso...@comcast-dot-net.invalid

Eric Sosman

unread,
Apr 3, 2013, 9:25:41 PM4/3/13
to
On 4/3/2013 8:24 PM, markspace wrote:
> On 4/3/2013 5:05 PM, Arne Vajh�j wrote:
>> But now you raise the question, then final is only slightly
>> involved in immutability in Java.
>>
>> If is neither sufficient nor necessary to make them
>> immutable.
>
> final is necessary. [...]

public class Immutable {
private int value;
public Immutable(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}

Claim: Immutable is immutable, despite the lack of "final".

--
Eric Sosman
eso...@comcast-dot-net.invalid

Lew

unread,
Apr 3, 2013, 9:31:21 PM4/3/13
to
markspace wrote:
> final is necessary. It is not sufficient (you also have to not mutate
> the object in question after the enclosing object's ctor exits). I'm
> pretty sure the field must also be explicitly private. (Implicitly

Nope.

You can have immutable public fields.

> might not be enough to satisfy what ever escape analysis the Java
> compiler does.)

'final' is essential to the definition of constant variables, which do have special
initialization semantics.

'final' is an essential piece in locking down an immutable reference variable of a type; call
this type 'ImmutableA'.

The object referenced by the member is immutable by dint of its implementation, which
we'll postulate to be correct.

public class ImmutableA
{
private String ident = "Immutable instance";
}

While the object referenced by 'ident' is immutable, this is not enough to make instances
of 'ImmutableA' immutable. For that you must have 'final'.

public class ImmutableA
{
private final String ident = "Immutable instance";
}

Now 'ImmutableA' instances are immutable. Not only that, but in this case, because
'ident' is 'final' and initialized by a constant expression, it is now a constant variable.

So 'final' is most assuredly involved in creating immutability, and is more reliable in the
face of refactoring and other maintenance to preserve it than immutability idioms that
do not use 'final'.

--
Lew

markspace

unread,
Apr 3, 2013, 9:34:24 PM4/3/13
to
Right and he goes on to say that String is an example. But String does
rely on final fields -- its char array is final -- and its immutability
derives directly from that. Brain Goetz also adds "don't try this at
home" meaning it's difficult to actually do. He's referring to the
idempotentcy [sic?] of its hash code -- but that doesn't work if the
char array is not final.

I'm just talking about the semantics about final here. I'm trying to
not focus on other implication of having a final field. I think the
subject is complicated enough with out introducing other ways to make an
object thread safe immutable. If you want, I'll agree that there are
exceptions, but I have to insist that final is the normal mechanic, and
if one doesn't understand final fields one won't understand the bits
that Brian Goetz says to "don't try this at home."



markspace

unread,
Apr 3, 2013, 9:37:07 PM4/3/13
to
Not in the sense of section 17.5 of the JLS, which is what I linked to
above (and also uses the term "thread safe immutable" to describe the
semantics of final fields).

And not in the sense that Brian Goetz uses in JCIP.


Lew

unread,
Apr 3, 2013, 9:41:39 PM4/3/13
to
Eric Sosman wrote:
> markspace wrote:
>> Arne Vajh�j wrote:
>>> But now you raise the question, then final is only slightly
>>> involved in immutability in Java.
>
>>> If is neither sufficient nor necessary to make them
>>> immutable.
>
>> final is necessary. [...]
>
> public class Immutable {
> private int value;
> public Immutable(int value) {
> this.value = value;
> }
>
> public int getValue() {
> return value;
> }
> }
>
> Claim: Immutable is immutable, despite the lack of "final".

'final' can help in some superficially similar scenarios.

public class MutableImmutable extends Immutable
{
private int foo;

public MutableImmutable(int av)
{
super(av);
foo = av;
}

@Override public int getValue()
{
return foo;
}

public void setValue(int av)
{
foo =av;
}
}

Now you can have code like this:

MutableImmutable mui = new MutableImmutable(0);
Immutable immu = mui;
System.out.println("Immutable value = " + immu.getValue());

mui.setValue(-1);
System.out.println("Immutable value = " + immu.getValue());

If the "mui" and "immu" code are in different parts of the application, e.g., one is
inside a method called separately from the other, you can have mutable behavior
from an 'Immutable' reference even though the parent class is actually immutable.

Furthermore, if 'Immutable#value' were not 'private', then the overriding class can
mutate the behavior of its parent, and break immutability, which is not possible if
the parent class defines 'value' to be 'final'.

So while 'final' is not necessary for immutability, it sure does help.

--
Lew

markspace

unread,
Apr 3, 2013, 9:46:35 PM4/3/13
to
On 4/3/2013 6:31 PM, Lew wrote:
> markspace wrote:
>> final is necessary. It is not sufficient (you also have to not mutate
>> the object in question after the enclosing object's ctor exits). I'm
>> pretty sure the field must also be explicitly private. (Implicitly
>
> Nope.
>
> You can have immutable public fields.
>

Well, that's true. I'm clearly getting a little sloppy in my language
with all the different posts I've been making.

A final field can be immutable and public if it's a primitive or if the
object it references is immutable. I think that covers it.

> public class ImmutableA
> {
> private final String ident = "Immutable instance";
> }
>
> Now 'ImmutableA' instances are immutable. Not only that, but in this case, because
> 'ident' is 'final' and initialized by a constant expression, it is now a constant variable.
>

And because String itself is immutable.

public class NotImmutable {
public final char[] string = {'a','b','c'};
}

final, public, initialized by a constant expression, but not immutable.

This is also immutable:

public class ImmutableB {
public final String string = "abc";
}

Can't change it, so it's OK to be public. Thread safe immutable.

(See my post to Eric, what the JLS actually says in section 17.5 is
"thread safe immutable", which is rather different from just
"immutable." I've been confusing the two terms in my posts when I
really should not. What I've really been talking about I should call
"thread safe immutable" to match the JLS.)


Arne Vajhøj

unread,
Apr 3, 2013, 9:54:29 PM4/3/13
to
"normal mechanic" is not the same as "necessary".

Arne


Arne Vajhøj

unread,
Apr 3, 2013, 9:57:25 PM4/3/13
to
The point of final for thread safeness is well known.

But using the distinct term "thread safe immutable" may
be very beneficial here to explain that this is not just
plain immutable.

Arne

markspace

unread,
Apr 3, 2013, 10:17:59 PM4/3/13
to
On 4/3/2013 6:20 PM, Eric Sosman wrote:
> I'm with Arne. The cited section uses the word "immutable"
> and "immutability" without defining either. All it says is that
> "final" can be an aid to implementing immutable objects -- but it
> never says what "immutable" is.

Well, it does. Section 17.5 has several subsections, and it's defined
in section 17.5.1. I feel one really should read all of 17.5 to
understand final fields however.

> It doesn't even say that "final"
> confers immutability; on the contrary, it says "final fields must
> be *used correctly* [emphasis mine] to provide a guarantee of
> immutability."

OK, that might be part of the problem. final is necessary but not
sufficient. I'll concede that, no problem. I misspoke if I implied
otherwise.

>
> Toward the end of the section, we're told that String is
> "perceived as truly immutable." So now there are two more notions:
> "truly immutable" as opposed to merely "immutable," and "perceived
> as truly immutable" as opposed to "actually truly immutable, not
> dependent on somebody's perception." Where does the JLS define how
> these three different kinds of immutability differ? Where does it
> *define* even one of them?

That's a bit of an issue. I think they're just using 'perceived' to
mean visible. There's a happens-before relationship between the end of
the ctor and all other threads in the system. So String is perceived as
immutable by all threads because its fields are visible.

I think immutable is defined in section 17.5.1, with their "hb(w, f),
hb(f, a), mc(a, r1), and dereferences(r1, r2)" stuff. That section is
as I say clear as mud, and I'm relying on Brian Goetz in JCIP to
interpret that mess correctly for me.

>
> Thought experiment: Using the JLS' definition of immutability,
> support or refute "java.lang.String is mutable, because it computes
> its hashCode() lazily and caches it in a non-final field, thereby
> changing the String object's state at the first hashCode() call."

But all threads will see the String's internal char[] to have the same
values, because it's safely published through a final field. So all
threads will calculate the same hash code. This isn't really "thread
safe," except that it is because being idempotent counts. Threads can
never seen any value for the internally stored hash code except 0 or the
correctly computed value.

>
> Thought experiment: Using the JLS' definition of immutability,
> support or refute "All Java objects are mutable, because all have a
> monitor whose state changes every time a synchronized block is
> entered or exited. The monitor's state affects the behavior of
> all threads attempting to synchronize on the object, so the change
> of state is not strictly internal but is visible to all observers."
>

Refutation: Only objects with proper final field semantics are immutable
under the JLS's definition. Only those objects are thread safe even
without accessing/invoking their monitor; this latter condition was
specified in that short sentence I quoted at the start of this whole
discussion.

"final fields also allow programmers to implement thread-safe immutable
objects without synchronization."

"Without synchronization" is the whole point of the way Java defines
immutability.



markspace

unread,
Apr 3, 2013, 10:23:24 PM4/3/13
to
On 4/3/2013 6:57 PM, Arne Vajhøj wrote:

>
> The point of final for thread safeness is well known.
>
> But using the distinct term "thread safe immutable" may
> be very beneficial here to explain that this is not just
> plain immutable.

OK, if that's the issue, then mea culpa. But the JLS and Brian Goetz
use "immutable" to mean "thread safe immutable." Immutable is being
used in a specific, technically defined way, and it's important to keep
that in mind when reading Java literature.

Does the author mean "just regular immutable" or "thread safe
immutable?" With Java, often it's going to be the latter, and I do mean
in the sense of the JLS when I use immutable to refer to final field
semantics.


Lew

unread,
Apr 3, 2013, 11:09:08 PM4/3/13
to
On Wednesday, April 3, 2013 6:46:35 PM UTC-7, markspace wrote:
> Lew wrote:
>> public class ImmutableA
>> {
>> private final String ident = "Immutable instance";
>> }
>>
>> Now 'ImmutableA' instances are immutable. Not only that, but in this case, because
>> 'ident' is 'final' and initialized by a constant expression, it is now a constant variable.
>
> And because String itself is immutable.

I said "and initialized by a constant expression", which is a stronger assertion than immutability.

It encompasses immutability, so the fact that String is immutable is covered by my comment.

> public class NotImmutable {
> public final char[] string = {'a','b','c'};
> }
>
> final, public, initialized by a constant expression, but not immutable.

It is *not* initialized by a constant expression!

I should have given the full term, a "compile-time constant expression" (JLS §15.28):
http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28
"A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following: [list of restricted syntax] ..."

The restricted syntax allows only certain expressions involving primitives or 'String's.

An array is neither primitive nor a 'String'.

> This is also immutable:
>
> public class ImmutableB {
> public final String string = "abc";
> }

'string' is also a constant variable.

> Can't change it, so it's OK to be public. Thread safe immutable.

Furthermore, it's a constant variable, so its visibility is different that it would be without 'final'.
Also, simply referencing a static constant variable does not invoke initialization of its containing class.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1

> (See my post to Eric, what the JLS actually says in section 17.5 is
> "thread safe immutable [sic]", which is rather different from just
> "immutable." I've been confusing the two terms in my posts when I
> really should not. What I've really been talking about I should call
> "thread safe immutable" to match the JLS.)

All "thread-safe immutable" means is immutable and not seen by another thread until after the
immutability is assured by a memory barrier.

--
Lew

Lew

unread,
Apr 3, 2013, 11:45:51 PM4/3/13
to
markspace wrote:
> Eric Sosman wrote:
>> I'm with Arne. The cited section uses the word "immutable"
>> and "immutability" without defining either. All it says is that
>> "final" can be an aid to implementing immutable objects -- but it
>> never says what "immutable" is.
>
> Well, it does. Section 17.5 has several subsections, and it's defined
> in section 17.5.1. I feel one really should read all of 17.5 to
> understand final fields however.

Section 17.5.1 never mentions the word "immutable" at all.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.1

Section 17.5, however, does define "thread-safe immutable":
" A thread-safe immutable object is seen as immutable by all threads, even if a data race is used to pass references to the immutable object between threads."

The word "immutable" is apparently to be understood in its common computer-science meaning.

[snip]
> I think immutable is defined in section 17.5.1, with their "hb(w, f),
> hb(f, a), mc(a, r1), and dereferences(r1, r2)" stuff. That section is
> as I say clear as mud, and I'm relying on Brian Goetz in JCIP to
> interpret that mess correctly for me.

That section does not address immutability, but finality.

It says that the value of a reference will not be seen to change if the conditions pertain,
but says nothing about the state of the object referenced.

>> Thought experiment: Using the JLS' definition of immutability,

There isn't one.

>> support or refute "java.lang.String is mutable, because it computes
>> its hashCode() lazily and caches it in a non-final field, thereby
>> changing the String object's state at the first hashCode() call."

Clearly they use "immutable" to refer to observable ("perceived") state.

Any two calls to a fully-constructed 'String' instance's 'hashCode()' will be perceived
to have the same value, and thus is immutable to conventional observation.

> But all threads will see the String's internal char[] to have the same
> values, because it's safely published through a final field. So all
> threads will calculate the same hash code. This isn't really "thread
> safe," except that it is because being idempotent counts. Threads can

Yes, it is really thread safe, assuming you wait for the ctor to complete.

> never seen any value for the internally stored hash code except 0 or the
> correctly computed value.

And if you follow the rules of thread-safe immutability, and I don't know how you would
dodge them for 'String', threads will never see 0.

--
Lew

markspace

unread,
Apr 3, 2013, 11:47:09 PM4/3/13
to
On 4/3/2013 8:09 PM, Lew wrote:
> I should have given the full term, a "compile-time constant
> expression" (JLS §15.28):
> http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28
>
> "A compile-time constant expression is an expression denoting a
> value of primitive type or a String that does not complete abruptly
> and is composed using only the following: [list of restricted
>syntax] ..."

Ah OK, a term a wasn't familiar with. Thanks for the info.

> Furthermore, it's a constant variable, so its visibility is different
> that it would be without 'final'. Also, simply referencing a static
> constant variable does not invoke initialization of its containing
> class.
> http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.1

I think I get this. Constant variables can be initialized at compile
time, and so so their visibility is compile time and later. An access
to a constant variable wouldn't cause a class to initialize, whereas an
access to my public final char[] would cause the whole class to initialize.

> All "thread-safe immutable" means is immutable and not seen by
> another thread until after the immutability is assured by a memory
> barrier.
>

Yes, but I think it's causing confusion, as Arne and possibly Joerg are
assuming that immutable means something more like the plain English
meaning of that word, and they're not taking into account the special
meaning applied by the JLS. I had to modify my terminology to be more
clear.

markspace

unread,
Apr 4, 2013, 12:30:16 AM4/4/13
to
On 4/3/2013 8:45 PM, Lew wrote:
> markspace wrote:
>> Eric Sosman wrote:
>>> I'm with Arne. The cited section uses the word "immutable" and
>>> "immutability" without defining either. All it says is that
>>> "final" can be an aid to implementing immutable objects -- but
>>> it never says what "immutable" is.
>>
>> Well, it does. Section 17.5 has several subsections, and it's
>> defined in section 17.5.1. I feel one really should read all of
>> 17.5 to understand final fields however.
>
> Section 17.5.1 never mentions the word "immutable" at all.
> http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.1

Huh, so it doesn't. OK, it just defines the semantics of final fields then.

>
> Section 17.5, however, does define "thread-safe immutable":
...
> The word "immutable" is apparently to be understood in its common
> computer-science meaning.

Section 17.5 says this in its second paragraph:

"final fields must be used correctly to provide a guarantee of
immutability."

That's the last sentence. To me that's ascribing special semantics to
just the word 'immutable.' If it's saying "final fields must be used"
then it's special for final fields. I realize there a qualifier on
that, but the qualifier is "correctly" and they're just pointing out
it's a little tricky. final fields must be used is the key point.
(Used incorrectly, of course, they won't guarantee immutability.)

I see how you might read that differently, but without final fields the
number of useful immutable classes is pretty small. (I'm ignoring
stateless objects here.)

>
> And if you follow the rules of thread-safe immutability, and I don't
> know how you would dodge them for 'String', threads will never see
> 0.

??? The first thread to calculate a hash code will always see 0.
That's what triggers the hash code calculation, rather than just
returning the value stored in the hash code field.



Leif Roar Moldskred

unread,
Apr 4, 2013, 1:42:34 AM4/4/13
to
markspace <mark...@nospam.nospam> wrote:
>
> Honestly I'm shocked at your response and I think you're missing the
> point by a wide margin. Are you trying to tell me that final fields are
> not involved in immutability in Java?
>

For what it's worth, they're not:

public class ThisIsImmutable {
private String cantChangeMe;

public ThisIsImmutable(String value) {
this.cantChangeMe = value;
}

public String getCantChangeMe() {
return this.cantChangeMe;
}
}


public class ThisIsNot {
private final Map<String, Integer> positionMap = new HashMap<>();

public void store(String key) {
this.positionMap.put(key, positionMap.size());
}

public Integer position(String key) {
return this.positionMap.get(key);
}

public void clear() {
this.positionMap.clear();
}
}


Now, it's certainly good practice to use "final" to help mark fields
that should not be reassigned, but "final" is neither sufficient nor
necessary to enforce immutability. (And with reflection mixed in the
bag it's not even sufficient to enforce non-reassignability, but
that's another story.)

As for the use of "final" for parameters and local variables, my
personal opinion is that the semantics of "final" are too weak to make
it worth the bother. As Java methods are pass-by-value, variable
reassignment just isn't a real source for problems so why guard
against it?

--
Leif Roar Moldskred
Message has been deleted

lipska the kat

unread,
Apr 4, 2013, 4:09:12 AM4/4/13
to
On 03/04/13 20:01, Joerg Meier wrote:
> On Wed, 03 Apr 2013 19:51:05 +0100, lipska the kat wrote:
>
>> [...] When I see the
>> modifier final it says something to me, it says, this value is not
>> modifiable ('scuse the pun).
>
> Then you need to read a Java beginner tutorial ;)

I read everything I can about Java, beginner or otherwise :)

There's a lot that's been added to this thread since I retired to my bed
last night and I haven't read it all so please excuse me if I'm
repeating what others have said.

one primitive and one reference variable

//x can be assigned once and once only
final int x = 0;

x++;
//ILLEGAL, x cannot be modified as it's final

//list can be assigned once and once only
final List<String> list = new ArrayList<String>();

//OK, the instance is not immutable
list.add("foo");

list = new ArrayList<String>();
//ILLEGAL, list cannot be modified as it's final

This is what I mean by not modifiable, the variables x and list are
not modifiable after assignment however what list points to, sorry
refers to is a mutable instance of ArrayList<String>, this is quite
different.

> "final" makes a variable or field impossible to reassign. It says
> absolutely nothing at all about whether or not that variables is
> modifiable.

I'm not sure I understand

> What you are thinking of is immutability, something that is not
> formalized in Java. In Java, having final mutable fields is perfectly
> legitimate.

Can you give an example?

thanks

lipska

--
Lipska the Kat©: Troll hunter, sandbox destroyer
and farscape dreamer of Aeryn Sun

Arved Sandstrom

unread,
Apr 4, 2013, 4:37:14 AM4/4/13
to
On 04/04/2013 05:09 AM, lipska the kat wrote:
> On 03/04/13 20:01, Joerg Meier wrote:
>> On Wed, 03 Apr 2013 19:51:05 +0100, lipska the kat wrote:
[ SNIP ]

>
>> What you are thinking of is immutability, something that is not
>> formalized in Java. In Java, having final mutable fields is perfectly
>> legitimate.
>
> Can you give an example?

This is more a matter of incorrect English. An *object* is mutable or
immutable, not a field. For variables or fields I'd never use the terms
mutable/immutable; I'd prefer simply "final" or "not final" or something
similar.

What Joerg meant is that if the final field is of a reference type then
it is perfectly possible that the object assigned to it is mutable.

AHS

paul....@gmail.com

unread,
Apr 4, 2013, 4:55:43 AM4/4/13
to
On Thursday, 4 April 2013 06:42:34 UTC+1, Leif Roar Moldskred wrote:
> markspace <mark...@nospam.nospam> wrote:
> >
> > ... Are you trying to tell me that final fields are
> > not involved in immutability in Java?
>
> For what it's worth, they're not:
>
> public class ThisIsImmutable {
> private String cantChangeMe;
> public ThisIsImmutable(String value) {
> this.cantChangeMe = value;
> }
> public String getCantChangeMe() {
> return this.cantChangeMe;
> }
> }

Interestingly, is "ThisIsImmutable" immutable given you can do this?

public class NowItIsnt extends ThisIsImmutable {
public String getCantChangeMe() {
return Integer.toString(new Random().nextInt());
}
}

Of course you could make ThisIsImmutable final.
Message has been deleted

Arved Sandstrom

unread,
Apr 4, 2013, 5:10:52 AM4/4/13
to
On 04/04/2013 05:59 AM, Stefan Ram wrote:
> Arved Sandstrom <asand...@eastlink.ca> writes:
>> This is more a matter of incorrect English. An *object* is mutable or
>> immutable, not a field. For variables or fields I'd never use the terms
>> mutable/immutable; I'd prefer simply "final" or "not final" or something
>> similar.
>
> JLS7 10.9 gives us:
>
> »A String object is immutable, that is, its contents
> never change, while an array of char has mutable elements.«
>
> »That is, its contents never change« seems to be a
> definition of »immutable«, at least for objects.
>
> »While an array of char has mutable elements« applies the
> term to variables of type char (here, anonymous variables),
> so it does not apply to objects only.
>
> (Obviously, »immutable« is »not mutable«, so that »mutable«
> and »immutable« are connected by a negation. Thus, a
> definition of one also doubles as a definition of the other.)
>
I'd call that unfortunate terminology myself, as per the array of char,
and I wish the author(s) hadn't done it. An array element *is* the item
at a given position in the array, and that may or may not be mutable
depending on the type of array. How is a primitive char mutable?

I would say that the *array* of char is mutable.

AHS
Message has been deleted

lipska the kat

unread,
Apr 4, 2013, 5:35:02 AM4/4/13
to
Something which I have never argued against.

There are no two ways about it, a final variable is not modifiable once
assigned to, the fact that the variable is a reference to a possibly
modifiable instance of something or other is irrelevant to my original
assertion.

A variable that is final is no longer variable, it is not modifiable, on
that I think we all agree.

Another enjoyable discussion.

Joerg Meier

unread,
Apr 4, 2013, 7:53:25 AM4/4/13
to
On Thu, 04 Apr 2013 09:09:12 +0100, lipska the kat wrote:

> There's a lot that's been added to this thread since I retired to my bed
> last night and I haven't read it all so please excuse me if I'm
> repeating what others have said.

Same here.

> //OK, the instance is not immutable
> list.add("foo");

This is the case I was referring to: making the reference to list final
does not make the list object immutable.

> This is what I mean by not modifiable, the variables x and list are
> not modifiable after assignment however what list points to, sorry
> refers to is a mutable instance of ArrayList<String>, this is quite
> different.

>> "final" makes a variable or field impossible to reassign. It says
>> absolutely nothing at all about whether or not that variables is
>> modifiable.
> I'm not sure I understand

I must admit that I didn't consider primitives in my wording. I was talking
mostly about mutable objects - making a final reference to them does not
prevent modifying the object. I fear the attempt to include primitives in
definitions like this is futile - I don't even know whether I would
consider primitives immutable or not. int i = 1; i++; // Does the 1 get
modified to a 2, or overwritten by a 2 ?

>> What you are thinking of is immutability, something that is not
>> formalized in Java. In Java, having final mutable fields is perfectly
>> legitimate.
> Can you give an example?

Yes, but I don't need to: you already did, it's the one I quoted above.
your list was a mutable final field.

Joerg Meier

unread,
Apr 4, 2013, 8:02:34 AM4/4/13
to
Correct. I disagreed with your statement (emphasis added by me):

On Wed, 03 Apr 2013 19:51:05 +0100, lipska the kat wrote:
> [...] When I see the
> modifier final it says something to me, it says, this *value* is not
> modifiable ('scuse the pun).

The variable/reference itself is not modifiable, but its VALUE certainly
is. And that, I feel, is the problem with using final to mean "this will be
the same throughout the code":

final Point p = new Point(0,0);

You can not be sure that the value of p will stay 0,0 throughout the code.

Joerg Meier

unread,
Apr 4, 2013, 8:07:52 AM4/4/13
to
On Tue, 02 Apr 2013 21:29:32 -0400, Arne Vajh�j wrote:

> I do not have a problem with 'slightly'.

I would be willing to settle on that as well after some more consideration.
My statement was in the heat of the moment, considering the overhead of
many small sort steps compared to one big, optimized sorting loop, but in
retrospect, that is unlikely to make as large an impact as I initially
thought.

If I get bored enough, I'll write some sort of benchmark, but I can't think
of a good way to get realistic 'somewhat sorted' test data, since honestly
the IO of getting filenames would completely crush any possible sort cost
on something that numbers so small.
It is loading more messages.
0 new messages