package reflection07;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.util.List;

/**
 * Vergleicht verscheiedene List-Implementationen. Dazu kann angegeben werden, welche
 * Implementation verwendet werden soll, diese wird dann mittels Reflect erzeugt und getestet.
 * 
 * @author Ralf Kunze (rkunze@uos.de), Institut fuer Informatik, Universitaet
 *         Osnabrueck
 * @date 02.06.2007
 */
public class TimedLists {

    public static void main(String[] args) {

        long zeit = 0;
        final int MAXVALUES = 5000;
        
        String listType = null;
        
        System.out.print("Bitte Klassenname einer List-Implementation eingeben:");
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        try {
            listType = br.readLine();
        } catch (IOException e1) {
           System.err.println("Kann nicht von stdin lesen");
           System.exit(1);
        }
        
        
        // Klasse laden
        Class<List<Integer>> c = null;
        try {
            c = (Class<List<Integer>>)Class.forName(listType);
        } catch (ClassNotFoundException e) {
            System.err.println("Die Klasse " + listType + " konnte nicht gefunden werden");
            System.exit(2);
        }
       
        // Stammt Klasse von List ab?
        if(!List.class.isAssignableFrom(c)) {
            System.err.println("Die Klasse " + listType + " ist keine Unterklasse von java.util.List");
            System.exit(3);
        }
        
        // Konstruktor holen
        Constructor<List<Integer>> constructor = null;
        try {
            constructor = c.getConstructor();
        } catch (SecurityException e) {
            e.printStackTrace();
            System.exit(110);
        } catch (NoSuchMethodException e) {
            System.err.println("Kein Defaultkonstruktor vorhanden");
            System.exit(4);
        }
        
        // Instanz erzeugen
        List<Integer> l = null;
        try {
            l = constructor.newInstance();
        } catch (Exception e) {
            System.err.println("Fehler bei der Instanziierung der Liste");
            System.exit(5);
        }
        
        // Test durchfuehren
        zeit = System.currentTimeMillis();
        for (int i = 0; i < MAXVALUES; i++) {
            l.add((int) (Math.random() * i), (int) (Math.random() * 1000));
        }
        System.out.printf(listType + ": Das Einfuegen an beliebigen Stellen hat %d Millisekunden gedauert.%n", System.currentTimeMillis() - zeit);

        zeit = System.currentTimeMillis();
        for (int i = 0; i < MAXVALUES; i++) {
            l.get((int) (Math.random() * MAXVALUES));
        }
        System.out
                .printf(
                        listType + ": Das Auslesen an beliebigen Stellen hat %d Millisekunden gedauert.%n",
                        System.currentTimeMillis() - zeit);
    }

}
