Search This Blog

Wednesday, October 10, 2012

How To Print A List of Comma-Seperated Values Nicely and Remove the Last (',') Comma Value


I recently wanted to take a list of Strings (i.e. List<String> list) and print that out with each value seperated by a comma and inside a set of brackets. The idea is I'd have something like this at the end:

    (String1,String2,String3)

However my first cut attempt at a loop was creating the list above but with a superfluous ',' at the end like so:

    (String1,Strng2,String3,)

Which was based on this code (where list was my List<String>):>

    StringBuilder sb = new StringBuilder("(");
    for (String string : list) {
        sb.append(string);
        sb.append(",");
    }
    sb.append(")");     //close the end bracket

So I decided to find a way or three to do this more nicely. What follows is 3 different ways of implementing this to get the correct implementation using a TestNG test case for testing. Each implementation, which achievs the same thing in each case is in one of the getVersion#() methods. Feel free to use any one of these 3 possible, simple implementations of the same thing to get the nicely comma seperated list with the end comma nicely removed.

  @Test
  public void testClass() {
    //Create a list of strings to be used in each test case
    List<String> list = new ArrayList<String>(Arrays.asList("String1", "String2", "String3"));
   
    //setup the expected result string based on the list above
    final String EXPECTED_RESULT = "(String1,String2,String3)";
   
    StringBuffer sb = getVersion1(list);
    System.out.println("1st string test:" + sb.toString());
    Assert.assertEquals(sb.toString(), EXPECTED_RESULT);
   
    sb = getVersion2(list);

    System.out.println("2nd string test:" + sb2.toString());
    Assert.assertEquals(sb2.toString(), EXPECTED_RESULT);
   
    sb = getVersion3(list);

    System.out.println("3rd string test:" + sb3.toString());
    Assert.assertEquals(sb3.toString(), EXPECTED_RESULT);
  }


  /**
   * This method puts the comma first so that we have the extra comma at the
   * start and then uses the deleteCharAt() method to delete the 1st ','
   */
  private StringBuffer getVersion1(List list) {
    //begin 1st case: ',' at start and deleteCharAt(0 or 1)
   
StringBuffer sb = new StringBuffer("(");
    for (String string : list) {
      sb.append(",");
      sb.append(string);
    }
    sb.deleteCharAt(1); //remove 1st ',' symbol (or if extra char's before bracket increse number)
    sb.append(")");     //close the end bracket


    return sb;
  }

  /**
   * This method puts the comma at the end in the common wayand then uses 
   * the deleteCharAt() method along with the length of the StringBuffer
   * to delete the last ',' symbol from the list before appending the ).
   */
  private StringBuffer getVersion2(List list) {
    //begin 2nd case: ',' at end and deleteCharAt(last character)
   
StringBuffer sb2 = new StringBuffer("(");
    for (String string : list) {
      sb2.append(string);
      sb2.append(",");
    }
    sb2.deleteCharAt(sb2.length() - 1); //remove the 1st ',' symbol
    sb2.append(")");     //close the end bracket


    return sb;
  }

  /**   
   * The final method of implementing this places the excess ',' at the end like 
   * is standard but then does the delete and append(")") steps in a single step
   * via the replace() call which replaces the lat ',' with the ')' bracket.
   */ 
  private StringBuffer getVersion3(List list) {
    //begin 3rd case:  ',' at end and replace the last character with the bracket achieving both at the same time
    StringBuffer sb3 = new
StringBuffer("(");
    for (String string : list) {
      sb3.append(string);
      sb3.append(",");
    }
    sb3.replace(sb3.length() - 1, sb3.length(), ")");


So there ya go, 3 different methods all very similar, to implement a comma-seperated list without the pesky comma at the end of the list and implemented in a TestNG test with Assertions to prove it worked as expected.  Note: In all 3 cases the performance is pretty much the same. When looking at the deleteCharAt() followed by an append() as compared to a replace() call they are pretty much identical in terms of what they are going to need to do. Although the internals vary the key performance hit is the call to the System.arrayCopy() which is where the time is spent. Either way there are 3 calls to System.arrayCopy() to perform this work, which reeally should be unsuprsing since in both cases we are doing pretty much the same thing just reducing the number of lines required to implement it. My choice is the 1st option as it looks the neatest (even if it does take one line more than the replace() method).

How To Use: javap With Eclipse IDE

I could write a blog post about this .... but instead ill let the following link do all the talking for me:

    http://stackoverflow.com/questions/7056987/how-to-use-javap-with-eclipse

So there ya go!

Wednesday, May 9, 2012

JDK8 Roadmap/Timeline to Release


JDK 8 Release Timeline Information


I’ve been following both the JDK7 and then JDK8 development blogs for java for some time now as they both have large numbers of changes to the language (much like the large number of changes in JDK5 (generics, enums etc) and unlike JDK6 which was not much of a change at all). Thought that you may be interested in the following links which now give a timeline for the release of the next Java version JDK8:

http://openjdk.java.net/projects/jdk8/

To quote from the above source, here is the proposed milestone development schedule:
2012/04/24 - M1
2012/06/14 - M2
2012/07/30 - M3
2012/09/11 - M4
2012/11/26 - M5
2013/01/30 - M6 – Feature Complete
2013/09/?? - GA – General Availability
The expectation at the end of M6 is that all features and new test development will be complete with the exception of work on component JSRs, which will be given additional time to bake until early May 2013. Between M6 and GA the tolerance for further changes will decrease in steps, with general bug fixes admitted up until early April 2013, only P1-P3 bug fixes until mid-June 2013, and only showstopper fixes after that.

This version should have the following main changes (of which the inclusion of closures/lambda calculus functionality will IMHO be one of the biggest changes ever introduced in Java ... larger even then the introduction of generics in JDK 5):

  • Project Coin – language changes...half of which were introduced in JDK7 and which you can read about on the web
  • Project Jigsaw – breaking up the monolithic sized JDK into separate MODULES with dependencies (a bit like Gradle/Maven/Ivy but for Java) ... more detail/links at: http://openjdk.java.net/projects/jigsaw/ and quickstart guide with examples on Mark Reinholds blog: http://openjdk.java.net/projects/jigsaw/doc/quickstart.html 
  • Project Lambda – long standing effort (discussed since JDK5 and maybe even earlier) to introduce closures and related functionality into java: http://openjdk.java.net/projects/lambda , see here for one of the latest documents providing information:  http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-4.html   IMHO this will be a huge change to Java and the way programming occurs (as this pushes java towards a LISP style functional programming type language) and this is without doubt the change I (and many other developers also) are looking forward to the most.

Its still a way away yet to the release date ... but worth keeping in mind when considering updates to the SOE used by your work place (or home projects) and when to make the jump from JDK6 to JDK7/8??

---------------------------
Notes: On JSR 337:

---------------------------


By the way the following link also has the dates for the JDK 8 JSR 337 Spec and its various Milestones:

http://openjdk.java.net/projects/jdk8/spec/

This is the primary web page for JSR 337, the Platform Umbrella JSR for Java SE 8.

Expert Group

  • Andrew Haley (Red Hat)
  • Steve Poole (IBM)
  • Mark Reinhold (Oracle)
  • TBD (Google)

Schedule

2012/7Expert Group formation
2012/9Early Draft Review
2013/1Public Review
2013/6Proposed Final Draft
2013/8Final Release

Mailing lists

There are two mailing lists:
  • java-se-8-spec-experts is the Expert Group (EG) list. Only EG members may subscribe and post to this list, but the archives are public.
  • java-se-8-spec-observers is for those who wish to monitor and, perhaps, discuss the EG's progress. Messages sent to the primary EG list are automatically forwarded to this list. Anyone may subscribe to this list, and any subscriber may post. EG members are under no obligation to follow the traffic on this list.
A formal feedback channel, most likely in the form of an issue tracker, will be set up when a draft specification is available for review.

Differences in Creating a Servlet in versions 2.5 and 3.0 Of the Servlet Spec.

Differences in Servlet Definitions between v2.5 and v3.0

The following 2 examples show the difference between how a Servlet Java Class and associated web.xml deployment descriptor was changed in the upgrade from version 2.5 to version 3.0 of the Servlet Specification. I found this a simple and interesting look at the way the definition of a Servlet in code has now been simplified through the use of annotations from JSR 175.

2.5 Version of Servlet Definition 

Java Class Of Servlet in 2.5

public class MyServlet extends HttpServlet {
    public void doGet (HttpServletRequest req, HttpServletResponse res) {
        ....
    }
}

Deployment descriptor in 2.5 (web.xml)

<web-app>
    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <servlet-class>samples.MyServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MyServlet</servlet-name>
        <url-pattern>/MyApp</url-pattern>
    </servlet-mapping>
    ...
</web-app>

3.0 Version of Servlet Definition 

Here is the much simplified version written to the Servlet 3.0 API. As MyServlet is annotated as a servlet using the @Servlet annotation, it gets initialized during the start-up of the web container. Note that the deployment descriptor is optional in this case.

Java Class Of Servlet in 3.0

@Servlet(urlMappings={"/MyApp"})
public class MyServlet {
    @GET
    public void handleGet(HttpServletRequest req, HttpServletResponse res) {
        ....
    }
}

Deployment descriptor in 3.0 (web.xml) - Optional