use Scanner class example

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangbingfengf98/article/details/85538334

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 can be made to work with more types. If you create a new class and you want it used with Scanner, you make it Readable(since 1.5), like this:

// 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

猜你喜欢

转载自blog.csdn.net/wangbingfengf98/article/details/85538334