Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #10387 > unrolled thread

for :each style question

Started byRoedy Green <see_website@mindprod.com.invalid>
First post2011-11-30 15:32 -0800
Last post2011-12-04 19:43 +0000
Articles 18 — 11 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  for :each style question Roedy Green <see_website@mindprod.com.invalid> - 2011-11-30 15:32 -0800
    Re: for :each style question Arne Vajhøj <arne@vajhoej.dk> - 2011-11-30 19:28 -0500
      Re: for :each style question Chris Riesbeck <Chris.Riesbeck@gmail.com> - 2011-12-05 14:28 -0600
    Re: for :each style question Knute Johnson <nospam@knutejohnson.com> - 2011-11-30 16:49 -0800
      Re: for :each style question Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2011-11-30 18:23 -0800
        Re: for :each style question Wanja Gayk <brixomatic@yahoo.com> - 2011-12-10 13:28 +0100
          Re: for :each style question Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2011-12-12 12:07 -0800
            Re: for :each style question Roedy Green <see_website@mindprod.com.invalid> - 2011-12-13 08:08 -0800
              Re: for :each style question Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2011-12-13 12:07 -0800
            Re: for :each style question Wanja Gayk <brixomatic@yahoo.com> - 2011-12-17 16:20 +0100
          Re: for :each style question Jim Janney <jjanney@shell.xmission.com> - 2011-12-14 14:31 -0700
            Re: for :each style question Lew <lewbloch@gmail.com> - 2011-12-14 16:53 -0800
              Re: for :each style question Daniel Pitts <newsgroup.nospam@virtualinfinity.net> - 2011-12-15 16:16 -0800
            Re: for :each style question Wanja Gayk <brixomatic@yahoo.com> - 2011-12-17 12:31 +0100
    Re: for :each style question Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-11-30 21:35 -0500
    Re: for :each style question Lew <lewbloch@gmail.com> - 2011-11-30 19:12 -0800
    Re: for :each style question Robert Klemme <shortcutter@googlemail.com> - 2011-12-01 23:36 +0100
    Re: for :each style question Steven Simpson <ss@domain.invalid> - 2011-12-04 19:43 +0000

#10387 — for :each style question

FromRoedy Green <see_website@mindprod.com.invalid>
Date2011-11-30 15:32 -0800
Subjectfor :each style question
Message-ID<30fdd7tlkkejm29ufduhc9nnfk7uu3c6h0@4ax.com>
In a for:each loop, sometimes you want to treat the first and or last
element specially.  

The obvious way to handle is to revert to a for int i= loop and check
for special values of i.

You can keep the for:each style if you have a boolean first= true that
you set false to detect the first.

I don't know of an equivalent way to detect the last.

In the olden days I would have handled the first and last cases
outside the loop, with the loop running over the middle elements. You
can't do that with for:each.

What do you consider the best style to deal with this?
-- 
Roedy Green Canadian Mind Products
http://mindprod.com
For me, the appeal of computer programming is that
even though I am quite a klutz,
I can still produce something, in a sense
perfect, because the computer gives me as many
chances as I please to get it right.
 

[toc] | [next] | [standalone]


#10388

FromArne Vajhøj <arne@vajhoej.dk>
Date2011-11-30 19:28 -0500
Message-ID<4ed6ca3e$0$291$14726298@news.sunsite.dk>
In reply to#10387
On 11/30/2011 6:32 PM, Roedy Green wrote:
> In a for:each loop, sometimes you want to treat the first and or last
> element specially.
>
> The obvious way to handle is to revert to a for int i= loop and check
> for special values of i.
>
> You can keep the for:each style if you have a boolean first= true that
> you set false to detect the first.
>
> I don't know of an equivalent way to detect the last.
>
> In the olden days I would have handled the first and last cases
> outside the loop, with the loop running over the middle elements. You
> can't do that with for:each.
>
> What do you consider the best style to deal with this?

first
for first+1 to last-1
last

Not much point in for(each) when it in fact is not for each.

Arne

[toc] | [prev] | [next] | [standalone]


#10534

FromChris Riesbeck <Chris.Riesbeck@gmail.com>
Date2011-12-05 14:28 -0600
Message-ID<9k4nrpFssU1@mid.individual.net>
In reply to#10388
On 11/30/2011 6:28 PM, Arne Vajhøj wrote:
> On 11/30/2011 6:32 PM, Roedy Green wrote:
>> In a for:each loop, sometimes you want to treat the first and or last
>> element specially.
>>
>> The obvious way to handle is to revert to a for int i= loop and check
>> for special values of i.
>>
>> You can keep the for:each style if you have a boolean first= true that
>> you set false to detect the first.
>>
>> I don't know of an equivalent way to detect the last.
>>
>> In the olden days I would have handled the first and last cases
>> outside the loop, with the loop running over the middle elements. You
>> can't do that with for:each.
>>
>> What do you consider the best style to deal with this?
>
> first
> for first+1 to last-1
> last
>
> Not much point in for(each) when it in fact is not for each.
>

While it's not a Java for:each loop, it's well within the concept of for 
each loops in general. The JSTL foreach element has some optional syntax 
for accessing just this kind of data :

    <c:forEach var="person" items="${group.members}" varStatus="status">
      ...
    </c:forEach>

Inside the forEach, status can tell you if you're first, last, etc.

    http://www.ibm.com/developerworks/java/library/j-jstl0318/

There are a couple of things I wish Java's for:each did. The other 
biggie is looping across several collections in parallel.

[toc] | [prev] | [next] | [standalone]


#10389

FromKnute Johnson <nospam@knutejohnson.com>
Date2011-11-30 16:49 -0800
Message-ID<jb6iv8$8j1$1@dont-email.me>
In reply to#10387
On 11/30/2011 3:32 PM, Roedy Green wrote:
> In a for:each loop, sometimes you want to treat the first and or last
> element specially.
>
> The obvious way to handle is to revert to a for int i= loop and check
> for special values of i.
>
> You can keep the for:each style if you have a boolean first= true that
> you set false to detect the first.
>
> I don't know of an equivalent way to detect the last.
>
> In the olden days I would have handled the first and last cases
> outside the loop, with the loop running over the middle elements. You
> can't do that with for:each.
>
> What do you consider the best style to deal with this?

public class test {
     public static void main(String[] args) {
         int ns[] = new int[23];
         int last = 0;

         for (int i=0; i<ns.length; i++)
             ns[i] = i;

         for (int n : ns) {
             last = n;
         }

         System.out.println(last);
     }
}

It's not elegant but it works.

-- 

Knute Johnson

[toc] | [prev] | [next] | [standalone]


#10391

FromDaniel Pitts <newsgroup.nospam@virtualinfinity.net>
Date2011-11-30 18:23 -0800
Message-ID<iyBBq.2059$2e7.1155@newsfe18.iad>
In reply to#10389
On 11/30/11 4:49 PM, Knute Johnson wrote:
> On 11/30/2011 3:32 PM, Roedy Green wrote:
>> In a for:each loop, sometimes you want to treat the first and or last
>> element specially.
>>
>> The obvious way to handle is to revert to a for int i= loop and check
>> for special values of i.
>>
>> You can keep the for:each style if you have a boolean first= true that
>> you set false to detect the first.
>>
>> I don't know of an equivalent way to detect the last.
>>
>> In the olden days I would have handled the first and last cases
>> outside the loop, with the loop running over the middle elements. You
>> can't do that with for:each.
>>
>> What do you consider the best style to deal with this?
>
> public class test {
> public static void main(String[] args) {
> int ns[] = new int[23];
> int last = 0;
>
> for (int i=0; i<ns.length; i++)
> ns[i] = i;
>
> for (int n : ns) {
> last = n;
> }
>
> System.out.println(last);
> }
> }
>
> It's not elegant but it works.
>

for:each is not useful for detecting last, and any acrobatics you go 
through to fix it are fairly pointless.

You would also have to handle the case where first=last (and/or is empty).

I find specific use-cases call for different approaches.  For instance, 
I like the following for string concatenation:

final StringBuilder builder = new StringBuilder();

String sep = "";

for (Object o: objects) {
    builder.append(sep).append(o);
    sep = ", ";
}

[toc] | [prev] | [next] | [standalone]


#10645

FromWanja Gayk <brixomatic@yahoo.com>
Date2011-12-10 13:28 +0100
Message-ID<MPG.294d6d4544cbb7e09896d5@202.177.16.121>
In reply to#10391
In article <iyBBq.2059$2e7.1155@newsfe18.iad>, 
newsgroup.nospam@virtualinfinity.net says...

> I find specific use-cases call for different approaches.  For instance, 
> I like the following for string concatenation:
> 
> final StringBuilder builder = new StringBuilder();
> 
> String sep = "";
> 
> for (Object o: objects) {
>     builder.append(sep).append(o);
>     sep = ", ";
> }

I always preferred to do it this way:

final StringBuilder builder = new StringBuilder();
final String sep = ", ";
for (final Object o: objects) {
    builder.append(o).append(sep);
}
builder.setLength(Math.max(0,builder.length()-sep.length()));

The only drawback is that the size of the builder's internal buffer may 
grow unnecessarily, if the last separator crosses its current bounds, 
but how often does that happen and how often is it really a problem?

Kind regards,
Wanja


-- 
..Alesi's problem was that the back of the car was jumping up and down 
dangerously - and I can assure you from having been teammate to 
Jean Alesi and knowing what kind of cars that he can pull up with, 
when Jean Alesi says that a car is dangerous - it is. [Jonathan Palmer]

--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---

[toc] | [prev] | [next] | [standalone]


#10679

FromDaniel Pitts <newsgroup.nospam@virtualinfinity.net>
Date2011-12-12 12:07 -0800
Message-ID<4atFq.37209$XA2.4561@newsfe06.iad>
In reply to#10645
On 12/10/11 4:28 AM, Wanja Gayk wrote:
> In article<iyBBq.2059$2e7.1155@newsfe18.iad>,
> newsgroup.nospam@virtualinfinity.net says...
>
>> I find specific use-cases call for different approaches.  For instance,
>> I like the following for string concatenation:
>>
>> final StringBuilder builder = new StringBuilder();
>>
>> String sep = "";
>>
>> for (Object o: objects) {
>>      builder.append(sep).append(o);
>>      sep = ", ";
>> }
>
> I always preferred to do it this way:
>
> final StringBuilder builder = new StringBuilder();
> final String sep = ", ";
> for (final Object o: objects) {
>      builder.append(o).append(sep);
> }
> builder.setLength(Math.max(0,builder.length()-sep.length()));
>
> The only drawback is that the size of the builder's internal buffer may
> grow unnecessarily, if the last separator crosses its current bounds,
> but how often does that happen and how often is it really a problem?
The *only* drawback?  Having to invoke a "Math" command is a drawback 
IMO. I like my approach because you can have a different starting 
separator.    Consider the case where you want parenthesis for one or 
more items, but an empty string for no items.:

String ender = "";
String sep = "(";
for (Object o: objects) {
    builder.append(sep).append(o);
    sep=", "; end=")";
}
builder.append(end);

Builds a parenthesized comma-separated list.  I have used this pattern 
frequently for SQL or HQL query builders.

[toc] | [prev] | [next] | [standalone]


#10706

FromRoedy Green <see_website@mindprod.com.invalid>
Date2011-12-13 08:08 -0800
Message-ID<fstee7h8asi1alauvpreufgb1hs6vp92g4@4ax.com>
In reply to#10679
On Mon, 12 Dec 2011 12:07:25 -0800, Daniel Pitts
<newsgroup.nospam@virtualinfinity.net> wrote, quoted or indirectly
quoted someone who said :

>String ender = "";
>String sep = "(";
>for (Object o: objects) {
>    builder.append(sep).append(o);
>    sep=", "; end=")";
>}
>builder.append(end);

I think that should read
String end = "";
-- 
Roedy Green Canadian Mind Products
http://mindprod.com
For me, the appeal of computer programming is that
even though I am quite a klutz,
I can still produce something, in a sense
perfect, because the computer gives me as many
chances as I please to get it right.
 

[toc] | [prev] | [next] | [standalone]


#10710

FromDaniel Pitts <newsgroup.nospam@virtualinfinity.net>
Date2011-12-13 12:07 -0800
Message-ID<VfOFq.25444$cN1.19057@newsfe12.iad>
In reply to#10706
On 12/13/11 8:08 AM, Roedy Green wrote:
> On Mon, 12 Dec 2011 12:07:25 -0800, Daniel Pitts
> <newsgroup.nospam@virtualinfinity.net>  wrote, quoted or indirectly
> quoted someone who said :
>
>> String ender = "";
>> String sep = "(";
>> for (Object o: objects) {
>>     builder.append(sep).append(o);
>>     sep=", "; end=")";
>> }
>> builder.append(end);
>
> I think that should read
> String end = "";
indeed, "ender" should be "end" (or vice versa).  I've become too 
reliant on IDE's auto-suggesting the correct thing...

[toc] | [prev] | [next] | [standalone]


#10825

FromWanja Gayk <brixomatic@yahoo.com>
Date2011-12-17 16:20 +0100
Message-ID<MPG.2956d17963f8b8b79896da@202.177.16.121>
In reply to#10679
In article <4atFq.37209$XA2.4561@newsfe06.iad>, 
newsgroup.nospam@virtualinfinity.net says...

> The *only* drawback?  Having to invoke a "Math" command is a drawback 
> IMO. 

Why? It's a speedy operation and a terse expression.

Kind regards,
Wanja

-- 
..Alesi's problem was that the back of the car was jumping up and down 
dangerously - and I can assure you from having been teammate to 
Jean Alesi and knowing what kind of cars that he can pull up with, 
when Jean Alesi says that a car is dangerous - it is. [Jonathan Palmer]

--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---

[toc] | [prev] | [next] | [standalone]


#10747

FromJim Janney <jjanney@shell.xmission.com>
Date2011-12-14 14:31 -0700
Message-ID<2pehw6alhc.fsf@shell.xmission.com>
In reply to#10645
Wanja Gayk <brixomatic@yahoo.com> writes:

> In article <iyBBq.2059$2e7.1155@newsfe18.iad>, 
> newsgroup.nospam@virtualinfinity.net says...
>
>> I find specific use-cases call for different approaches.  For instance, 
>> I like the following for string concatenation:
>> 
>> final StringBuilder builder = new StringBuilder();
>> 
>> String sep = "";
>> 
>> for (Object o: objects) {
>>     builder.append(sep).append(o);
>>     sep = ", ";
>> }
>
> I always preferred to do it this way:
>
> final StringBuilder builder = new StringBuilder();
> final String sep = ", ";
> for (final Object o: objects) {
>     builder.append(o).append(sep);
> }
> builder.setLength(Math.max(0,builder.length()-sep.length()));
>
> The only drawback is that the size of the builder's internal buffer may 
> grow unnecessarily, if the last separator crosses its current bounds, 
> but how often does that happen and how often is it really a problem?

import org.apache.commons.lang.StringUtils;

...

String joinedObjects = StringUtils.join(objects, ", ");

Not to go all Lew on you here, but the Apache Commons stuff is worth a
second look.

-- 
Jim Janney

[toc] | [prev] | [next] | [standalone]


#10759

FromLew <lewbloch@gmail.com>
Date2011-12-14 16:53 -0800
Message-ID<31677245.18.1323910421101.JavaMail.geo-discussion-forums@yqnd19>
In reply to#10747
Jim Janney wrote:
> Wanja Gayk writes:
>> newsgrou...@virtualinfinity.net says...
>>
>>> I find specific use-cases call for different approaches.  For instance, 
>>> I like the following for string concatenation:
>>> 
>>> final StringBuilder builder = new StringBuilder();
>>> 
>>> String sep = "";
>>> 
>>> for (Object o: objects) {
>>>     builder.append(sep).append(o);
>>>     sep = ", ";
>>> }
>>
>> I always preferred to do it this way:
>>
>> final StringBuilder builder = new StringBuilder();
>> final String sep = ", ";
>> for (final Object o: objects) {
>>     builder.append(o).append(sep);
>> }
>> builder.setLength(Math.max(0,builder.length()-sep.length()));
>>
>> The only drawback is that the size of the builder's internal buffer may 
>> grow unnecessarily, if the last separator crosses its current bounds, 
>> but how often does that happen and how often is it really a problem?
> 
> import org.apache.commons.lang.StringUtils;
> 
> ...
> 
> String joinedObjects = StringUtils.join(objects, ", ");
> 
> Not to go all Lew on you here,

You flatter me, sir.

> but the Apache Commons stuff is worth a second look.

... and a third, and a fourth, ...

That said, there are things in Commons that I would not, or not any longer, use, necessarily.  You don't want to use a hammer to unscrew a rivet.  But it is good to have a hammer in your toolkit when you need to pound in a nail.

-- 
Lew

[toc] | [prev] | [next] | [standalone]


#10782

FromDaniel Pitts <newsgroup.nospam@virtualinfinity.net>
Date2011-12-15 16:16 -0800
Message-ID<C5wGq.26282$cN1.3272@newsfe12.iad>
In reply to#10759
On 12/14/11 4:53 PM, Lew wrote:
> Jim Janney wrote:
>> Wanja Gayk writes:
>>> newsgrou...@virtualinfinity.net says...
>>>
>>>> I find specific use-cases call for different approaches.  For instance,
>>>> I like the following for string concatenation:
>>>>
>>>> final StringBuilder builder = new StringBuilder();
>>>>
>>>> String sep = "";
>>>>
>>>> for (Object o: objects) {
>>>>      builder.append(sep).append(o);
>>>>      sep = ", ";
>>>> }
>>>
>>> I always preferred to do it this way:
>>>
>>> final StringBuilder builder = new StringBuilder();
>>> final String sep = ", ";
>>> for (final Object o: objects) {
>>>      builder.append(o).append(sep);
>>> }
>>> builder.setLength(Math.max(0,builder.length()-sep.length()));
>>>
>>> The only drawback is that the size of the builder's internal buffer may
>>> grow unnecessarily, if the last separator crosses its current bounds,
>>> but how often does that happen and how often is it really a problem?
>>
>> import org.apache.commons.lang.StringUtils;
>>
>> ...
>>
>> String joinedObjects = StringUtils.join(objects, ", ");
>>
>> Not to go all Lew on you here,
>
> You flatter me, sir.
>
>> but the Apache Commons stuff is worth a second look.
Oh, I use StringUtils (and other commons lang classes) frequently. That 
wasn't the point.
>
> .... and a third, and a fourth, ...
>
> That said, there are things in Commons that I would not, or not any longer, use, necessarily.  You don't want to use a hammer to unscrew a rivet.  But it is good to have a hammer in your toolkit when you need to pound in a nail.
>

I haven't followed the latest versions of commons-lang in a while... 
Have they gotten their collections support (lazy maps, etc...) to be 
generic yet?

[toc] | [prev] | [next] | [standalone]


#10823

FromWanja Gayk <brixomatic@yahoo.com>
Date2011-12-17 12:31 +0100
Message-ID<MPG.29569bf9e0974ead9896d8@202.177.16.121>
In reply to#10747
In article <2pehw6alhc.fsf@shell.xmission.com>, 
jjanney@shell.xmission.com says...

> import org.apache.commons.lang.StringUtils;
> 
> String joinedObjects = StringUtils.join(objects, ", ");
> 
> Not to go all Lew on you here, but the Apache Commons stuff is worth a
> second look.

For sure, and I use it everywhere I see it. Some customers though do not 
use the library and do not intend to do so.

Kind regards,
Wanja


-- 
..Alesi's problem was that the back of the car was jumping up and down 
dangerously - and I can assure you from having been teammate to 
Jean Alesi and knowing what kind of cars that he can pull up with, 
when Jean Alesi says that a car is dangerous - it is. [Jonathan Palmer]

--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---

[toc] | [prev] | [next] | [standalone]


#10393

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-11-30 21:35 -0500
Message-ID<jb6p6j$7q5$1@dont-email.me>
In reply to#10387
On 11/30/2011 6:32 PM, Roedy Green wrote:
> In a for:each loop, sometimes you want to treat the first and or last
> element specially.
>
> The obvious way to handle is to revert to a for int i= loop and check
> for special values of i.
>
> You can keep the for:each style if you have a boolean first= true that
> you set false to detect the first.
>
> I don't know of an equivalent way to detect the last.
>
> In the olden days I would have handled the first and last cases
> outside the loop, with the loop running over the middle elements. You
> can't do that with for:each.
>
> What do you consider the best style to deal with this?

     I once taught a student whose DO loops (this was FORTRAN) always
iterated from 1 through N, never from 2 through N or 1 through N-1.
Paraphrasing into zero-based Java, he'd write something like

	for (int i = 0; i < array.length; ++i) {
	    if (i == 0) continue;
	    if (i == array.length - 1) continue;
	    massage(array[i-1], array[i], array[i+1]);
	}

     I was unable to break him of this habit, and eventually formed
the opinion that he had learned The One True Way to write a loop,
and Nothing On Earth would persuade him to write it differently.

     That's the wrong way to think about a tool.

     The for:each form is a convenience, a prepackaged solution to
a common problem.  Do not expect it to be the answer for all kinds
of iteration.  for:each is Java's feeble imitation of (mapc); don't
push it beyond its built-in limits.  There are lots of other looping
forms available; use them when they suit.

     (For those who don't know what (mapc) means, see the current
thread "java developers" and give special attention to Patricia
Shanahan's contribution.)

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#10396

FromLew <lewbloch@gmail.com>
Date2011-11-30 19:12 -0800
Message-ID<3484881.48.1322709135595.JavaMail.geo-discussion-forums@prdv33>
In reply to#10387
Roedy Green wrote:
> In a for:each loop, sometimes you want to treat the first and or last
> element specially.  
> 
> The obvious way to handle is to revert to a for int i= loop and check
> for special values of i.
> 
> You can keep the for:each style if you have a boolean first= true that
> you set false to detect the first.
> 
> I don't know of an equivalent way to detect the last.
> 
> In the olden days I would have handled the first and last cases
> outside the loop, with the loop running over the middle elements. You
> can't do that with for:each.
> 
> What do you consider the best style to deal with this?

Regular 'for' loop (or its 'while' or 'do...while' cousins).

For:each is for a particular use case where it helps.  For other use cases, you probably shouldn't use it.

-- 
Lew

[toc] | [prev] | [next] | [standalone]


#10406

FromRobert Klemme <shortcutter@googlemail.com>
Date2011-12-01 23:36 +0100
Message-ID<9jqdqlFkoaU1@mid.individual.net>
In reply to#10387
On 12/01/2011 12:32 AM, Roedy Green wrote:
> In a for:each loop, sometimes you want to treat the first and or last
> element specially.
>
> The obvious way to handle is to revert to a for int i= loop and check
> for special values of i.
>
> You can keep the for:each style if you have a boolean first= true that
> you set false to detect the first.
>
> I don't know of an equivalent way to detect the last.

The trick for detecting the last element is to defer evaluation of each 
element by one iteration and handle the last one after the loop.

> In the olden days I would have handled the first and last cases
> outside the loop, with the loop running over the middle elements. You
> can't do that with for:each.
>
> What do you consider the best style to deal with this?

For the fun of it, here is one way to do it - although I find it quite 
silly:

package clj;

import java.util.Arrays;

public final class FirstLast {

	private static enum Pos {
		NONE, FIRST, LATER
	}

	public static <T> void firstLast(final Iterable<T> items) {
		Pos p = Pos.NONE;
		T last = null;

		for (final T item : items) {
			switch (p) {
			case NONE:
				p = Pos.FIRST;
				break;
			case FIRST:
				System.out.println("First: " + last);
				p = Pos.LATER;
				break;
			case LATER:
				System.out.println("Next: " + last);
				break;
			}

			last = item;
		}

		if (p != Pos.NONE) {
			System.out.println("Last: " + last);
		}
	}

	public static void main(String[] args) {
		System.out.println("empty");
		firstLast(Arrays.asList());
		System.out.println("one");
		firstLast(Arrays.asList("a"));
		System.out.println("two");
		firstLast(Arrays.asList("a", "b"));
		System.out.println("more");
		firstLast(Arrays.asList("a", "b", "c", "d"));
	}

}

Kind regards

	robert

[toc] | [prev] | [next] | [standalone]


#10492

FromSteven Simpson <ss@domain.invalid>
Date2011-12-04 19:43 +0000
Message-ID<m3vsq8-45n.ln1@news.simpsonst.f2s.com>
In reply to#10387
On 30/11/11 23:32, Roedy Green wrote:
> In a for:each loop, sometimes you want to treat the first and or last
> element specially.  [...]
> What do you consider the best style to deal with this?

If I needed it a lot...

import java.util.Arrays;
import java.util.List;

public class FirstLastLoop {
     interface FirstLastBlock<T>  {
         void invoke(T t, boolean isFirst, boolean isLast);
     }

     static<T>  void forEach(Iterable<? extends T>  coll,
                             FirstLastBlock<? super T>  block) {
         boolean isFirst = true;
         boolean lastHeld = false;
         T last = null;
         for (T t : coll) {
             if (lastHeld) {
                 block.invoke(last, isFirst, false);
                 isFirst = false;
             }

             last = t;
             lastHeld = true;
         }
         if (lastHeld)
             block.invoke(last, isFirst, true);
     }

     public static void main(String[] args) throws Exception {
         List<String>  list = Arrays.asList(args);

         FirstLastBlock<String>  block = new FirstLastBlock<String>() {
             public void invoke(String t, boolean isFirst, boolean isLast) {
                 if (isFirst)
                     System.out.print("The list: ");
                 else if (isLast)
                     System.out.print(" and ");
                 else
                     System.out.print(", ");
                 System.out.print(t);
                 if (isLast)
                     System.out.println('.');
             }
         };

         forEach(list, block);

         // Lambda version
         forEach(list, (t, isFirst, isLast) ->  {
                 if (isFirst)
                     System.out.print("The list: ");
                 else if (isLast)
                     System.out.print(" and ");
                 else
                     System.out.print(", ");
                 System.out.print(t);
                 if (isLast)
                     System.out.println('.');
             });
     }
}



-- 
ss at comp dot lancs dot ac dot uk

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web