use Scanner class example
A common use for interfaces is the aforementioned Strategy design pattern. You write a method that performs certain operations, and that method takes an interface you also specify. You’re basically saying, “You can use my method with any object you like, as long as your object conforms to my interface.” This makes your method more flexible, general and reusable.
For example, the constructor for the Scanner class takes a Readable interface. You’ll find that Readable is not an argument for any other method in the Java standard library—it was created solely for Scanner , so Scanner doesn’t constrain its argument to a particular class. This way, Scanner
// interfaces/RandomStrings.java // (c)2017 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. // Implementing an interface to conform to a method import java.nio.*; import java.util.*; public class RandomStrings implements Readable { private static Random rand = new Random(47); private static final char[] CAPITALS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); private static final char[] LOWERS = "abcdefghijklmnopqrstuvwxyz".toCharArray(); private static final char[] VOWELS = "aeiou".toCharArray(); private int count; public RandomStrings(int count) { this.count = count; } @Override public int read(CharBuffer cb) { // CharBuffer since 1.4, but I do not find This abstract class in openjdk package nio source code. find in jdk r.jar if(count-- == 0) return -1; // Indicates end of input cb.append(CAPITALS[rand.nextInt(CAPITALS.length)]); for(int i = 0; i < 4; i++) { cb.append(VOWELS[rand.nextInt(VOWELS.length)]); cb.append(LOWERS[rand.nextInt(LOWERS.length)]); } cb.append(" "); return 10; // Number of characters appended } public static void main(String[] args) { Scanner s = new Scanner(new RandomStrings(10)); while(s.hasNext()) System.out.println(s.next()); } } /* Output: Yazeruyac Fowenucor Goeazimom Raeuuacio Nuoadesiw Hageaikux Ruqicibui Numasetih Kuuuuozog Waqizeyoy */
Suppose you have a type that does not already implement Readable —how do you make it work with Scanner ? Here’s an example that produces random floating point numbers:
// interfaces/RandomDoubles.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
import java.util.*;
public interface RandomDoubles {
Random RAND = new Random(47); // static & final
default double next() {
return RAND.nextDouble();
}
static void main(String[] args) {
RandomDoubles rd = new RandomDoubles() {};
for (int i = 0; i < 7; i++) System.out.print(rd.next() + " ");
// RAND = new Random(); // compile error
}
}
/* the interface has main() method.
My Output:
0.7271157860730044 0.5309454508634242 0.16020656493302599 0.18847866977771732 0.5166020801268457 0.2678662084200585 0.26136
10344283964
*/
We can use the Adapter pattern, but here the adapted class can be created by implementing both interfaces. So, using the multiple inheritance provided by the interface keyword, we produce a new class which is both RandomDoubles and Readable:
// interfaces/AdaptedRandomDoubles.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Creating an adapter with inheritance
import java.nio.*;
import java.util.*;
public class AdaptedRandomDoubles implements RandomDoubles, Readable {
private int count;
public AdaptedRandomDoubles(int count) {
this.count = count;
}
@Override
public int read(CharBuffer cb) {
if (count-- == 0) {
return -1;
}
String result = Double.toString(next()) + " ";// diff
cb.append(result);
return result.length();
}
public static void main(String[] args) {
Scanner s = new Scanner(new AdaptedRandomDoubles(7));
while (s.hasNextDouble()) {
System.out.print(s.nextDouble() + " ");
}
}
}
/* My Output:
0.7271157860730044 0.5309454508634242 0.16020656493302599 0.18847866977771732 0.5166020801268457 0.2678662084200585 0.26136
10344283964
BUILD SUCCESSFUL
Total time: 1.471 secs
*/
references:
1. On Java 8 - Bruce Eckel
2. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/interfaces/RandomStrings.java
3. http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/java/lang/Readable.java
4. http://developer.classpath.org/doc/java/nio/CharBuffer-source.html
5. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/interfaces/RandomDoubles.java
6. https://github.com/wangbingfeng/OnJava8-Examples/blob/master/interfaces/AdaptedRandomDoubles.java