Per un’introduzione sulla classe Scanner vedi: Java: la classe Scanner.



La classe Scanner consente di leggere dei token da diverse fonti (File, InputStream, String…). Può tuttavia capitare di dover leggere da una qualche struttura diversa. In questo caso ci viene in aiuto il costruttore:

Scanner(Readable source)

e la capacità di Scanner di avere come fonte un Readable

java.lang.Readable è un interfaccia con un solo metodo:

int read(CharBuffer cb)

Lo scanner si aspetta quindi che il buffer sia riempito dal Readable. Il lancio di un’eccezione IOException da parte del Readable viene interpretato come fine dell’input dallo scanner.

Supponiamo di voler dunque usare lo scanner per leggere un array di stringhe simile a questo:

["Audi", "BMW", "Fiat"]

La prima idea sarebbe quella di creare un’unica stringa a partire dagli elementi dell’array e usare lo scanner su di essa:

// qui ci va la stringa creata a partire dall'array
Scanner scanner = new Scanner("Audi BMW Fiat");
while(scanner.hasNext())
  System.out.println(scanner.next());

Un’altra idea è quella di wrappare l’array in un oggetto che implementa Readable.
Ad ogni read invocata sul wrapper aggiorneremo l’indice dell’elemento corrente:

import java.io.IOException;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class ArrayReadable implements Readable {
  private List<String>  list;
  private int           idx;

  public ArrayReadable(List<String> list) {
    this.list = list;
  }

  @Override
  public int read(CharBuffer cb) throws IOException {
    if(idx == list.size()) {
      throw new IOException("EOF");
    }
    if(idx < 0 || idx > list.size()) {
      throw new IOException("Illegal ArrayReadable state");
    }    

    String currstr = list.get(idx++);
    cb.append(currstr).append(' ');
    return currstr.length();
  }

  public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    list.add("Audi");
    list.add("BMW");
    list.add("Fiat");
    ArrayReadable array = new ArrayReadable(list);
    Scanner scanner = new Scanner(array);
    while(scanner.hasNext())
      System.out.println(scanner.next());
  }
}