TIL #7: Java Lambda Puzzler

Today, a colleague asked me how they can pass a java.util.Stream to a function that accept an java.lang.Iterable.

Let’s suppose we have a following function that accepts an Iterable.

public static void doSth(Iterable<String> iterable){
        iterable.forEach(System.out::println);
 }

The calling function has a Stream that it want to pass to the doSth function.

public static void main(String[] args) throws IOException {
        Stream<String> lines = Files.lines(Paths.get("src", "main", "resources", "names.txt"));
}

One way we could easily achieve this is by collecting the Stream into a Collection like List. As List is an Iterable so we can pass it. This is should below

Stream<String> lines = Files.lines(Paths.get("src", "main", "resources", "names.txt"));
doSth(lines.collect(Collectors.toList()));

This works but what if Stream is big and collecting into an in-memory data structure like List leads to java.lang.OutOfMemoryError: Java heap space.

I googled around and found a nice Lambda hack.

Stream<String> lines = Files.lines(Paths.get("src", "main", "resources", "names.txt"));
doSth(lines::iterator);

I have worked a lot on Java 8 but first time I looked at it I couldn’t figure out how it works. If you know Java 8, give it a shot.

The magic here is that Iterable interface has a single abstract method iterator.

public interface Iterable<T> {
    Iterator<T> iterator();
}

This means we can write it as following Lambda function.

Iterable<T> iterable = () -> iterator();

In our case, Stream has an iterator method. So, we can convert Stream to Iterable by defining a lambda function as shown below.

Stream<String> lines = Files.lines(Paths.get("src", "main", "resources", "names.txt"));
doSth(() -> lines.iterator());

You can refactor the Lambda to a method reference.

Stream<String> lines = Files.lines(Paths.get("src", "main", "resources", "names.txt"));
doSth(lines::iterator);

Can we use () -> iterator() in the for-each loop

I wondered if we can use the lambda expression in the for-each loop

for (String str : () -> lines.iterator()) {
    System.out.println(str);
}

This looks like a valid use case. As for-each loop works with types that implement Iterable interface. But, it turns out the code does not compile. It gives Lambda expression not implemented here error.

The answer for this is mentioned in the JSR335

Deciding what contexts are allowed to support poly expressions 
is driven in large part by the practical 
need for such features:

The expression in an enhanced for loop is not in a 
poly context because, as the construct is currently defined, 
it is as if the expression were a receiver: 
exp.iterator() (or, in the array case, exp[i]). 
It is plausible that an Iterator could be wrapped 
as an Iterable in a for loop via a 
lambda expression (for (String s : () -> stringIterator)), 
but this doesn't mesh very well with the semantics of Iterable.

Another Interesting thing to note is that Iterable is not marked as @FunctionalInterface. I don’t know the exact reason why Iterable is not marked as @FunctionalInterface. My guess is that because Iterable has special semantics in Java so they didn’t explicitly marked it @FunctionalInterface.

IBM DeveloperWorks Introducing Spring Roo, Part 4: Rapid application development in cloud with Spring Roo and Cloud Foundry

Take the rapid development of Roo a step further by creating applications to work in the cloud with Cloud Foundry, the first open platform as a service project created by VMWare. Learn more about the environment and then deploy an application into Cloud Foundry using the Roo shell. Read about it here http://www.ibm.com/developerworks/opensource/library/os-springroo4/index.html

Java Puzzler : They just find me !!

Couple of days back I wrote a piece of code which was behaving in an unexpected manner. I was confused what was happening. Take a look at the sample code below and predict its behavior

package com.shekhar;

public class JavaPuzzler {

	public static void main(String[] args) {
		JavaPuzzler javaPuzzler = new JavaPuzzler();
		javaPuzzler.doSth();
	}

	public void doSth() {
		float f = 1.2f;
		if (f >= 1.0) {
			f = 0.9999999999999f;
		}
		InnerClass innerClass = new InnerClass(f);
		System.out.println(innerClass.getValue());
	}

	private class InnerClass {

		private float value;

		public InnerClass(float value) {
			if (value >= 1.0f) {
				throw new IllegalArgumentException(
						"Value can't be greater than 1.0f");
			}

			this.value = value;
		}

		public float getValue() {
			return value;
		}
	}
}

My initial expectation was that I would get value 0.9999999999999f as answer.Try it and find the answer. Share your answer and reasoning in comments.

Top 10 New Features in Maven 3

Maven 3.0 was just released and the Java build tool has come a long way since version 2 was released almost six years back. Maven 2 had reached a stage where it was difficult to extend and its code was difficult to understand. In version 3.0 many of the Maven internals have been revamped to overcome all the issues associated with Maven 2. In this article, I run down the top 10 features in Maven 3.

Read More

New Java Puzzler Found while reading Java Puzzler book

Today, while solving puzzles from Java Puzzler book I myself created a new Java Puzzle. So, in this blog I am writing about that puzzle.

Puzzle

Will the code given below results in an infinite loop.


public class MyJavaPuzzle {

 public static void main(String[] args) {
 Double i = Double.NaN;
 while(i != i){
 System.out.println("Infinite Loop");
 }
 }
}

Solve this puzzle and have fun. Happy Puzzling!!!

Post your answer and explanation in comments.

Java Puzzlers on local variable initialization

Intent of my blog

Some time back, i posted a blog on common interview questions on overriding.The blog was very popular on dzone so i decided to write some of the java puzzlers on local variable initialization.One thing which should be kept in mind is that Local variables should be initalized before they are used.Knowing this fact try to answer these questions.

Local Variable Initialization Puzzlers

Question1


public class Question1{
 public static void main(String[] args) {
 int x;
 int y = 10;
 if (y == 10) {
 x = y;
 }
 System.out.println("x is " + x);
 }
}

Question 2


class Question2{
 public static void main(String[] args) {
 int x;
 if(true){
 x = 10;
 }
 System.out.println("x is " + x);
 }
}

Question 3


class Question3{
 public static void main(String[] args) {
 int x;
 final int y = 10;
 if(y == 10){
 x = 10;
 }
 System.out.println("x is " + x);

 }
}

Question 4


class Question4{
 static int y = 10;

 public static void main(String[] args) {
 int x ;
 if(y == 10){
 x = 10;
 }
 System.out.println("x is " + x);
 }
}

Question 5


class Question5{
 static final int y = 10;

 public static void main(String[] args) {
 int x ;
 if(y == 10){
 x = 10;
 }
 System.out.println("x is " + x);
 }
}

Again, like the previous post, i am not posting the solutions because i dont want to take away the fun. So, play with these and have fun.

Again fallen into java puzzler trap– Another Java Puzzler

Intent of My Blog
Today, while writing a piece of code, i found that i have again fallen into a java trap.This is a java puzzler that i read in java puzzler book.

What is the output of this java puzzler?

public class JavaPuzzler {

public static void main(String[] args) {
JavaPuzzler javaPuzzler = null;
System.out.println(javaPuzzler.get());
}

private static String get(){
return "i am a java puzzler";
}

}

Before reading the answer ,please try running this in eclipse and see whether you got it correct.

Solution

You might think that it should throw NullPointerException because the main method invokes get() method  on local variable which is initialized to null, and you can’t invoke a method on null.

But if you run this program, you will see that it prints “i am a java puzzler” . The reason  is that get() is a static method.

Does Java Puzzlers make Good Interview Questions?

Intent of my Blog

Recently i wrote an blog entry on one of the java puzzlers that was asked to me in an interview.I received some of the comments which said this is unfair to ask java puzzlers in an interview.So i thought of writing an blog which discusses whether java puzzlers make good interview questions or not.

Does Java Puzzlers make Good Interview Questions?

I think before answering this question that should we ask java puzzlers in an interview or not we need to define some guidelines about what makes a good interview question. And if java puzzlers fit within those guidelines then we can ask the them in an interview.I am giving my personal point of view please add in your comments if you think something different.

Guideline for a Good Technical Interview Question

  1. Question should be How not what = Should be Practical which means that Interviewer should not ask the definition of some term or concept the interview question should be such that it discusses  practical application of concept.Asking how has the advantage that interviewer gets the correct feedback about interviewee that interviewee actually understand the concept.
  2. Question should be on simpler concepts = Asking a difficult question doesn’t make an interview question good.In my personal opinion interview question should be about the concepts which a developer normally use. You can vary the difficulty level of question depending upon position you are hiring but the concept should be simple.For example you can ask questions on overriding which can be simple or difficult but the concept of overriding is such that every java developer should know.
  3. Question can be Extended =  A good interview question should be such that you can build your interview on that question which means that if you ask a question on overriding you can start with the easier question and then build your interview by asking questions that increases in difficulty.
  4. Question should not be specific to API = The question that i mentioned in my post was good but it was specific to the HashSet remove method arguments. Let me explain, when you create an hashset  like HashSet<Short> s = new HashSet<Short>() you might expect that when you are doing s.remove(i-1) should remove only short objects but when you take a look at the remove method it takes Object .This is something specific to api which  most of the developers might not know. So asking such a question becomes useless.
  5. Question should provide a learning point = A good interview question should provide a value add to the interviewee. It might be possible that interviewee knows everything which is great and you can hire him/her. But even if he/she doesn’t know the answer they can at least  learn a good technical point.

Does java puzzlers fit these guidelines?

In my view java puzzler fit some of the guidelines:-

  1. All Java Puzzler are about How not What so java puzzlers can provide interviewer the practical understanding of the interviewee.
  2. Java Puzzlers are about simpler concepts but the Puzzlers are not simple because they discuss the trap or corner cases of the API. You can use these concepts for interviews but the questions are very specific to api and most of the times should not be asked in interview.
  3. Java Puzzlers can be extended but again because they are not easy most of the times you will not get the correct answer.
  4. Java Puzzlers are specific to API and they require very good understanding of java api.
  5. Java Puzzlers definitely provide a learning value to interviewee because these questions touches the corner cases  of the api which normally developers doesn’t know.

Conclusion

In my view you can ask some of the java puzzlers in an interview as java puzzlers definetly provide a value. Sometimes you should only take a concept and build you question on that and sometime take the whole question. If you think the java puzzler you are asking is difficult and a normal developer who hasn’t read java puzzlers book can’t answer please dont make that question a decider question means your decision to hire a person should not be based only on  java puzzler. Java Puzzlers are definetly very good questions and you should use them wisely in interview.

These are some of my view points. Please share your also.

Java Puzzlers are asked in interviews

Intent of my Blog

This blog is about one of the question that i was asked in an interview two years back. I forgot this question but yesterday i again faced this question and this is a “java puzzler”.

Question

Yesterday while looking for videos on “java puzzlers” i found out link on youtube by Joshua Bloch.When i started viewing this video one of the puzzle reminded of a question i was asked in an interview two years back. Although this question is not in Java(TM) Puzzlers: Traps, Pitfalls, and Corner Cases but it is one of the question i thought worth sharing.Try this question and have fun.

public class JavaPuzzler{
    public static void main(String[] args) {
        HashSet<Short> s = new HashSet<Short>();//1
        for(short i = 0; i<100;i++){//2
            s.add(i);//3
            s.remove(i-1);//4
        }
        System.out.println(s.size());//5
    }
}

Before viewing the answer of this question please try guessing the answer to this question and then run code in eclipse to check whether you what you were thinking matches the answer.If the answer amaze you it is a java puzzler.

Answer

Answer of this puzzler is 100.

To understand why we get 100 as answer lets try to understand the code line by line.

In line 1 we created an HashSet which is of type java.lang.Short .

In line 2 we are doing a for loop

In line3 we are adding short primitive which will be autoboxed to Short object  to the HashSet Collection.

In line 4, we are trying to remove an element from HashSet, which we added just before the current element. But there is a small gotcha (can you guess what is it?), the gotcha is when we do s.remove(i-1),  first of all expression (i -1) is evaluated in which short is widened to int and then int is converted to Integer object. This is due to autoboxing in java 1.5 version.If you look into the javadoc of remove method of HashSet, you will find that it takes an Object, so you can remove Integer objects  from HashSet of Short objects, but this will not work as a result none of the Short objects will get removed.

So in line 5 we get output as 100.

Hope you find this puzzle interesting, i will strongly recommend viewing this presentation.

You can share any of yours interview question which you think is a “java puzzler”.

Java Puzzlers are found in day to day work

Intent of my Blog

Today i was writing a piece of code and found one java puzzle. When i debugged it, i remembered that i read it something like this when i was reading  Java(TM) Puzzlers: Traps, Pitfalls, and Corner Cases .

Java Puzzle

Today while doing my day to day office work i found one java puzzle which i thought was worth writing.

Can you guess what is the output of following  java code:-

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String[] arr = {"java ","puzzlers ","is ","a ","good ","book"};
		String message = null;
		for(String str : arr){
			message += str;
		}
		System.out.println(message);
	}

}

I am posting the answer as well as the solution to overcome this problem.But first try this java puzzler yourself.Run this piece of code in eclipse and see what you guessed is correct.

Answer
If you ran this code you will get nulljava puzzlers is a good book
but you might be thinking that it should print java puzzlers is a good book If you don’t know that when you are concatenating the string null is taken as a string and was appended to the result . + operator is overridden for string so it does the concatenation for you.

The Easiest Solution to this problem can be initializing message with empty string rather than null.

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String[] arr = {"java ","puzzlers ","is ","a ","good ","book"};
		String message = "";// replacing null with empty string
		for(String str : arr){
			message += str;
		}
		System.out.println(message);
	}

}

But this solution also has a problem and that problem is related to performance because when you are iterating over array you are doing String using concatenation in a loop. In each iteration, the String is converted to a StringBuffer/StringBuilder, appended to, and converted back to a String.This can lead to decrease in performance of your program.
The best solution is the use of StringBuilder class.

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String[] arr = {"java ","puzzlers ","is ","a ","good ","book"};
		StringBuilder message =  new StringBuilder();
		for(String str : arr){
			message.append(str);
		}
		System.out.println(message.toString());
	}

}

If you think there is anyother better solution please put that in comment.