I have made very simple code to larn the functionality.

String str = "ABC";
        InputStream input = new ByteArrayInputStream(str.getBytes());

        BufferedReader reader = new BufferedReader(new InputStreamReader(input));
        System.out.println(Character.valueOf((char) reader.read()));

Secondly this one,

String str = "ABC";
        InputStream input = new ByteArrayInputStream(str.getBytes("UTF-8"));


output is same for the ways. Which way is good, and when should I use the each one of them? Thanks.

InputStream reads bytes one at a time - no character set processing and no buffering. It's the parent class for stream input, but rarely used becuase one of its subclasses is usually more appropriate (eg BufferedReader)

BufferedReader reads characters and buffers its input.

If your input is text, always use BufferedReader.

So, when should I use ByteArrayInputStream? I am confused little bit. I have used this also. But don't know when to use it specifically? Can you provide one case where this will be useful? I mean I want to get the essence of this class.

That's where the source of your data is already in memory as an array of bytes. If your data is in a byte array use that class. If not, don't use it.

The only time I've used it is with XMLEncode/Decode because they work to/from streams but i wanted the encoded data in memory, not in a disk file or socket

Another way to explain it:

ByteArrayInputStream, FileInputStream etc give you access to the raw bytes, one at a time, in the source array/file/whatever. These are lowest-level way to access the data. Chode the one corresponding to the data source.

There are two very useful ways to wrap those streams:
- a Buffered wrapper buffers the input for efficiency so it's not processed one byte at a time. It's hard to think of a case where you would NOT want to buffer.
- a Reader converts bytes to UniCode chars according to a specified or default character set encoding. You would always use this for text data, never for anything else.

So. if your text data is in a byte array you need to start with a ByteArrayInputStream, and wrap that in Reader. (The byte array is the one data source where buffering doesn't gain you anything, but it won't do any harm either.)

Nice explanation boss. Then, why do we do it this way? I mean :

new BufferedReader(new InputStreamReader(input));

why we make the inputStreamReader first? I want to know in deph little bit. What is the significance of InputStreamReader in this case?

Because there are two different wrapping processes going on.
First you wrap the byte-oriented input stream in a character-oriented Reader, then you buffer those characters in a Buffered stream