# Problem bei einer Aufgabe



## Naeva (24. Apr 2007)

Ich sollte im zuge einer Aufgabe mehrere Klassen verändern, zu einem währe die Table.java die ich auch meiner Ansicht nach richtig geändert habe, laut Test file sind noch 2 fehler bei put und get drin die ich aber nicht finde, hier mal das was ich geschrieben habe!

Table.java

```
public class Table implements ITable {

/**
 * Dies solle die erstmalige Groesse von data sein!
 */

   private static final int DEFAULT_INITIAL_SIZE = 4;

/**
 * Fertige Hilfsklasse für einzelne Einträge.
 */

   private static class Entry {
      private final Object key;
      private Object value;
      public Entry(Object key, Object value) {

        this.key = key;
        this.value = value;
        }
      public Object getKey() {
        return key;
        }
      public Object getValue() {
        return value;
        }

     public Object setValue(Object value) {
        Object oldValue = this.value;
        this.value = value;
        return oldValue;
        }
      }

   private int size=0;
   private Entry[] data = new Entry[DEFAULT_INITIAL_SIZE];
    
/**
 * Gibt die Anzahl der gespeicherten Eintragungen zurück.
 *
 * @return Anzahl der eingetragenen Datensätze.
 */
 
   public int size() {
      return size;
      }
/**
 * Trägt ein Objekt unter einem Suchbegriff ein.
 * Wenn der Suchbegriff bereits vorhanden, wird die zugehörige
 * Objektreferenz überschrieben und das vorher dort gespeicherte
 * Objekt wird zurückgegeben. Wenn bisher unter dem Schlüssel kein
 * Objekt gespeichert war, wird <code>null</code> zurückgegeben.
 *
 * @param key Suchschlüssel.
 * @param value Inhaltsobjekt.
 * @return vorheriger Eintrag oder <code>null</code>.
 * @throws NullPointerException wenn <code>key == null</code>.
 */
  
   public Object put(Object key, Object value)  {
      if(key==null) throw(new NullPointerException());
      int index=getIndex(key);
      if (index!=-1) { //Key exists
        return data[index].setValue(value);
        }
      else { //New Entry
        if(size>=data.length) { //data full, expand array
          Entry[] datatmp=new Entry[size*2];
          for(int i=0;i<data.length;i++)
          datatmp[i]=data[i];
          data=datatmp;
          }
        data[size]=new Entry(key,value);
        size++;
        return null;
        }
      }

/**
 * Gibt das unter einem Suchbegriff gespeicherte Objekt zurück.
 *
 * @param key Suchschlüssel.
 * @return gefundenes Objekt oder <code>null</code>.
 * @throws NullPointerException wenn <code>key == null</code>.
 */
   public Object get(Object key) {
      if(key==null) throw(new NullPointerException());
      int index=getIndex(key);
      if (index==-1) return null;
      return data[index].value;
      }

/**
 * Stellt fest, ob der Suchschlüssel in der Tabelle eingetragen ist.
 *
 * @param key Suchschlüssel.
 * @return <code>true</code> wenn vorhanden.
 * @throws NullPointerException wenn <code>key == null</code>.
 */
   public boolean containsKey(Object key) {
      if(key==null) throw(new NullPointerException());
      return (getIndex(key)!=-1);
      }
      
/**
 * Entfernt den Eintrag zu dem angegebenen Suchschlüssel.
 * Wenn kein Eintrag zu dem Schlüssel gefunden wird, wird
 * <code>null</code> zurückgegeben.
 *
 * @param key Suchschlüssel.
 * @return bisher gespeichertes Objekt oder <code>null</code>.
 * @throws NullPointerException wenn <code>key == null</code>.
 */
   public Object remove(Object key) {
      if(key==null) throw(new NullPointerException());
      int index=getIndex(key);
      if(index!=-1) { //Key exists
        Object ret=data[index].value;
        data[index]=data[size-1];
        size--;
        return ret;
        }
      else { //Key not found
        return null;
        }
      }
/**
 * Gibt ein Feld mit allen Suchschlüsseln zurück.
 *
 * @return Feld aller Schlüssel.
 */
   public Object[] keys() {
      Object[] ret=new Object[size];
      for(int i=0;i<size;i++)
      ret[i]=data[i].key;
      return ret;
      }
      
    private int getIndex(Object key) {
      if (key==null) throw(new NullPointerException());
      int res=-1;
      for(int i=0;i<size;i++)
      {
    if(data[i].key.equals(key))return i; }
      return res;
      }
      
    public void debug() {
      System.out.println("Debug der Tabelle\nSize: "+size+" Length: "+data.length);
      for(int i=0;i<size;i++) {
        System.out.println(i+": "+data[i].toString());
        System.out.println("\t Key: "+data[i].key+"\t Entry:"+data[i].value);
        }
      }
    }
```

Eine dazugehörige ITable.java (wurde nichts verändert)


```
public interface ITable {

    /**
     * Gibt die Anzahl der gespeicherten Eintragungen zurück.
     * 
     * @return Anzahl der eingetragenen Datensätze.
     */
    public int size();

    /**
     * Trägt ein Objekt unter einem Suchbegriff ein.
     * Wenn der Suchbegriff bereits vorhanden, wird die zugehörige
     * Objektreferenz überschrieben und das vorher dort gespeicherte
     * Objekt wird zurückgegeben. Wenn bisher unter dem Schlüssel kein
     * Objekt gespeichert war, wird <code>null</code> zurückgegeben.
     * 
     * @param key Suchschlüssel.
     * @param value Inhaltsobjekt.
     * @return vorheriger Eintrag oder <code>null</code>.
     * @throws NullPointerException wenn <code>key == null</code>.
     */
    public Object put(Object key, Object value);

    /**
     * Gibt das unter einem Suchbegriff gespeicherte Objekt zurück.
     * 
     * @param key Suchschlüssel.
     * @return gefundenes Objekt oder <code>null</code>.
     * @throws NullPointerException wenn <code>key == null</code>.
     */
    public Object get(Object key);

    /**
     * Stellt fest, ob der Suchschlüssel in der Tabelle eingetragen ist.
     * 
     * @param key Suchschlüssel.
     * @return <code>true</code> wenn vorhanden.
     * @throws NullPointerException wenn <code>key == null</code>.
     */
    public boolean containsKey(Object key);

    /**
     * Entfernt den Eintrag zu dem angegebenen Suchschlüssel.
     * Wenn kein Eintrag zu dem Schlüssel gefunden wird, wird
     * <code>null</code> zurückgegeben.
     * 
     * @param key Suchschlüssel.
     * @return bisher gespeichertes Objekt oder <code>null</code>.
     * @throws NullPointerException wenn <code>key == null</code>.
     */
    public Object remove(Object key);

    /**
     * Gibt ein Feld mit allen Suchschlüsseln zurück.
     * 
     * @return Feld aller Schlüssel.
     */
    public Object[] keys();
}
```

Dann noch eine Addressbook.java die auch geändert wurde


```
package praktikum2.a2;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;


public final class Addressbook implements IAddressbook {
    private ITable addresses = new Table();
    
    /**
     * Konstruktor.
     * Wenn die Eingabedatei nicht vorhanden ist, wird ein
     * leeres Adressbuch angelegt.
     * 
     * @param inFile Name der Eingabedatei.
     */
    Addressbook(String inFile) {
        restoreData(inFile);
        saveOnExit(inFile);
    }

    /**
     * Diese Methode liest, falls vorhanden, anfängliche Daten
     * aus der angegebenen Datei.
     * 
     * @param inFile Dateiname.
     */
    private void restoreData(String inFile) {
        try {
            DataInputStream in =
                new DataInputStream(
                    new BufferedInputStream(new FileInputStream(inFile)));
            int n = in.readInt();
            for (int i = 0; i < n; i++)
                addAddress(new Address(in));
            in.close();
        }
        catch (FileNotFoundException ignore) {
            // ignored: we start with an empty table
        }
        catch (IOException fatal) {
            fatal.printStackTrace();
            System.err.println("\nVermutlich ist file.dat defekt!");
            System.err.println("Am besten wird file.dat geloescht.");
            System.exit(1);
        }
    }

    /**
     * Diese Methode sorgt dafür, dass alle Dateninhalte in der
     * angegebenen Datei gespeichert werden.
     * 
     * @param fileName Dateiname.
     */
    private void saveOnExit(final String fileName) {
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                try {
                    DataOutputStream out =
                        new DataOutputStream(
                            new BufferedOutputStream(
                                new FileOutputStream(fileName)));
                    String[] keys = getNicknames();
                    out.writeInt(keys.length);
                    for (int i = 0; i < keys.length; i++)
                        getAddress(keys[i]).save(out);
                    out.close();
                }
                catch (IOException fatal) {
                    fatal.printStackTrace();
                }
            }
        });
    }
    
    public void addAddress(IAddress address) {
    	addresses.put(address.getNickname(),new Address(address.getNickname(),address.getFirstname(),address.getLastname(),address.getMailAddress()));
    	//addresses.put(nickname, new Address(nickname, firstname, lastname, mailAddress));
    	/* TODO: richtigen Aufruf einfuegen! */
    }

    public void addAddress(
        String nickname,
        String firstname,
        String lastname,
        String mailAddress) {
        addresses.put(nickname, new Address(nickname, firstname, lastname, mailAddress));
    }

    public boolean contains(String name) {
       if(addresses.containsKey((String)name)) return true;
    	/* TODO: richtigen Aufruf einfuegen! */
    	return false;
    }

    public IAddress getAddress(String name) {
        Object k = addresses.get(name);
    	return (IAddress) k;
    }

    public String[] getNicknames() {
        Object[] k = addresses.keys();
        String[] s = new String[k.length];
        System.arraycopy(k, 0, s, 0, k.length);
        return s;
    }

    public void remove(String name) {
        addresses.remove(name);
    }
}
```

dann noch eine IAddressbook.java wo nichts geändert wurde


```
public interface IAddressbook {
    
    /**
     * Trägt eine neue Adresse in das Adressbuch ein.
     * Der Parameter <code>nickname</code> ist der Schlüsselbegriff.
     * Wenn der Schlüssel bereits in dem Adressbuch vorhanden ist,
     * werden die Inhalte mit den neuen Werten überschrieben.
     * 
     * @param nickname Kurzname.
     * @param firstname Vorname.
     * @param lastname Familienname.
     * @param mailAddress Email-Adresse.
     */
    public void addAddress(
        String nickname,
        String firstname,
        String lastname,
        String mailAddress);

    /**
     * Fügt eine Email-Adresse in das Verzeichnis ein.
     * Adress-Objekte sind hinsichlich ihrem Kurznamen (nickname)
     * eindeutig.
     * 
     * @param address Adressobjekt.
     */
    public void addAddress(IAddress address);

    /**
     * Sucht nach den Adressdaten.
     * Wenn nicht gefunden, wird <code>null</code> zurückgegeben.
     * 
     * @param name Kurzname.
     * @return Adressobjekt.
     */
    public IAddress getAddress(String name);

    /**
     * Überprüft ob der Kurzname bereits als Suchschlüssel verwendet wurde.
     * 
     * @param name Kurzname
     * @return <code>true</code> wenn Kurzname vorhanden ist.
     */
    public boolean contains(String name);
    
    /**
     * Entfernt Adressdaten aus dem Adressbuch.
     * Wenn keine Daten zu <code>name</code> gefunden werden,
     * bewirkt der Aufruf nichts.
     * 
     * @param name Kurzname der Adressdaten.
     */
    public void remove(String name);
    
    /**
     * Erzeugt ein Feld mit allen Kurznamen.
     * 
     * @return Feld der Kurznamen.
     */
    public String[] getNicknames();
}
```

und die Main.java


```
final class Main {
    private Main() { }
    
    public static void main(String[] args) {
         new UserInterface(new Addressbook("file.dat"));
    }
}
```


----------



## Neva (24. Apr 2007)

Das Compilieren klappt wunderbar jedoch beim Ausführen der Main kommen folgende Fehlermeldungen

Exception in thread "main" java.lang.InternalError: Can´t connect to X11 Windowserver using :0.0 as the value Display variable
at sun.awt.X11GraphicsEnviroment.initDisplay(Native Method)

usw usw usw

Ich verzweifel hier langsam ^^


----------



## L-ectron-X (24. Apr 2007)

Es wäre wesentlich einfacher, wenn du die Originalfehlermeldung posten würdest.


----------



## Naeva (24. Apr 2007)

hab mal nen screenshot gemacht


----------



## The_S (24. Apr 2007)

Versuchst du zufällig eine Java-Anwendung die das AWT-Package verwendet auf einem Linux-System ohne Bildschrim/grafische Ausgabemöglichkeit zu starten?


----------



## Naeva (24. Apr 2007)

Ich sitze zuhause und hab mich mit unserem UNI server verbunden, zuhause XP (wie wohl die meisten) und auf dem Uni Server Unix


----------



## The_S (24. Apr 2007)

Da keine Anzeige auf dem Unix-Server funktioniert auch kein AWT. Du hast jetzt folgende Möglichkeiten:

a) Auf jegliche AWT-Elemente in deiner Anwendung verzichten
b) entsprechende Parameter in der VM des Servers setzen (müsste ich raussuchen)


----------



## Naeva (24. Apr 2007)

Aber das war doch alles von unserem Prof vorgegeben???

Also müsste es funktionieren wenn ich an einem Rechner in der Uni sitze und es da mache.

Und warum kommen diese 2 Fehlermeldungen wenn ich mit Eclipse das Test file laufen lasse?

Bei put und get? Compilieren klappt ja einwandfrei und wenn ich die Main nicht ausführen kann , ist es etwas schwer zu sehen ob es jetzt funktioniert oder nicht


----------



## The_S (24. Apr 2007)

Sobald du AWT verwendest, aber keine grafische Ausgabemöglichkeit auf dem Server hast und die VM nicht entsprechend konfiguriert ist, wirst du da gar nichts zum Laufen bringen. Da kann dein Prof noch so viel gemacht und gesagt haben  .


----------



## Naeva (24. Apr 2007)

hmmm ok kann man denn irgendwie an dem quellcode sehen ob die 2 methoden put und get richtig sind?  da da das test file noch bisschen meckert


----------



## The_S (24. Apr 2007)

Wenn du sagst was sie machen sollen und was genau für einen Fehler angezeigt wird ...

Generell gesagt, schmeißt du uns hier ein paar Brocken hin und zwei Sätze dazu. Daraus kann man dir nicht viel helfen. Mal ausgenommen von der Fehlermeldung, die ist ja ziemlich eindeutig  .


----------



## Naeva (24. Apr 2007)

Ja stimmt schon sry  bin das erste mal hier und langsam am verzweifel da ich schon seit 4 tagen an dieser aufgabe sitze 

Also hier die fehlermeldung vom Test File (Eclipse) auf dem Uni Server kann ich das Test file auch nicht ausführen da dann die selbe fehlermeldung kommt wie vorher (Screenshot) 

Runs 8/8  Errors 0  Failures 2

testOneputGet - Table Test

junit.framework.AssertionFailedError: Es wurden 4 Vergleiche erwartet, aber 14 gezählt
	at junit.framework.Assert.fail(Assert.java:47)
	at junit.framework.Assert.assertTrue(Assert.java:20)
	at TableTest.testOnePutGet(TableTest.java:109)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at junit.framework.TestCase.runTest(TestCase.java:154)
	at junit.framework.TestCase.runBare(TestCase.java:127)
	at junit.framework.TestResult$1.protect(TestResult.java:106)
	at junit.framework.TestResult.runProtected(TestResult.java:124)
	at junit.framework.TestResult.run(TestResult.java:109)
	at junit.framework.TestCase.run(TestCase.java:118)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

testOverwriting

junit.framework.AssertionFailedError: zuviele Vergleiche!
	at junit.framework.Assert.fail(Assert.java:47)
	at junit.framework.Assert.assertTrue(Assert.java:20)
	at TableTest.testOverwriting(TableTest.java:124)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at junit.framework.TestCase.runTest(TestCase.java:154)
	at junit.framework.TestCase.runBare(TestCase.java:127)
	at junit.framework.TestResult$1.protect(TestResult.java:106)
	at junit.framework.TestResult.runProtected(TestResult.java:124)
	at junit.framework.TestResult.run(TestResult.java:109)
	at junit.framework.TestCase.run(TestCase.java:118)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)


----------



## The_S (24. Apr 2007)

Irgendwo haust du 10 Vergleiche zu viel rein. Ohne tieferes Hintergrundwissen kann man da net viel sagen, zumal das keine Standardklasse ist, die die Fehlermeldung ausgiebt.


----------



## Naeva (24. Apr 2007)

Hmmm ok dann geb ich es wohl auf  danke trotzdem


----------



## The_S (24. Apr 2007)

Wenn du meinst ... Hier mal für die Lösung für das Telnet Problem:

http://www.adobe.com/go/tn_19252



> This is most likely because the server doesn't have a graphical subsystem (i.e. a graphics card and monitor). The Flex server uses Java's AWT (Abstract Window Toolkit) to implement compile time image embedding and SVG. By default, the Java Virtual Machine tries to use the hardware-based graphical capabilities of the machine to implement AWT. For servers without a graphical interface, the above error will be thrown.





> To resolve this issue, set the system propertyjava.awt.headless to true so that the JVM will implement AWT in software, rather than attempting to use non-existent hardware-based graphics.
> 
> Note: java.awt.headless is only available with JDK 1.4 and above. It is not available on previous versions of the JDK.
> 
> ...



Warum steht das überhaupt in Aufgaben und Gesuche?


----------



## kleiner_held (24. Apr 2007)

> Using the command line:
> 
> -D java.awt.headless=true


Damit wird man aber trotzdem kein JFrame sehen, da sich das nun mal nicht durch eine Telnet Session durchschleussen laesst.

Der Schalter macht nur Sinn, wenn man z.B. BufferedImage's im Speicher manipulieren will und dafuer keinen X-Server braeuchte.


----------



## The_S (24. Apr 2007)

Hat jemals jemand was anderes behauptet?


----------



## kleiner_held (24. Apr 2007)

Hobbit_Im_Blutrausch hat gesagt.:
			
		

> Hat jemals jemand was anderes behauptet?


Nein, ehrlich gesagt wollte ich nur mal schlau tun.


----------



## Naeva (24. Apr 2007)

Hmm weils ne Aufgabe ist? 
 Wie gesagt bin das erste mal hier wenns hier falsch ist dann sry

denke mein fehler ist der das ich zuviele schleifen drin habe aber wüsste nicht wie ich es ändern soll, daher dachte ich hier wüsste jemand rat ;(


----------



## The_S (24. Apr 2007)

in Aufgaben und Gesuche kommen die Threads rein, bei denen z. B. Hausaufgaben vollständig für Geld erledigt werden sollen.

Normalerweiße wird dir hier schon immer geholfen. Aber bei einem Projekt, bei dem keiner so weiß um was es geht, was geht, was nicht geht, usw. ist es nunmal sehr schwer dir zu helfen  .


----------



## Guest (24. Apr 2007)

Aso das wusste ich nicht, ich versuchs nochmal bisschen mehr zu erläutern

Aufgabe 1:

Table.java erstellen bzw ändern, die hab ich gemacht, sieht man auf der ersten Seite auch den Quellcode
zu beachtende Dateien. ITable.java und TableTest.java (vollständig vorgegeben)

Bei der Table.java sind halt noch diese 2 Fehlermeldungen drin ich denke ich habe zuviele Schleifen verwendet daher wird der Test nicht korrekt ausgeführt (siehe Fehlermeldung)

Aufgabe 2:

Addressbook.java ändern, Quellcode auf der ersten seite
zu beachtende Dateien IAddress.java, IAddressbook.java und Main.java (die 3 waren auch vorgegeben)

Im prinzip ist das ein Programm für eine Art Email Adressbuch, es startet mit einem leeren file (file.dat) dann sollte ein Grafik Fenster aufgehen wo man die Email Adresse, Name usw eingeben kann und beim beenden automatischh gespeichert wird

das wars


----------



## The_S (24. Apr 2007)

Und wie schauts original aus? Wie sollen die Klassen verändert werden (also was soll am Ende anders sein, als beim Original)? Welche Rollen spielen die beiden anderen Klassen dabei jeweils?


----------



## Naeva (24. Apr 2007)

Original ist in der Table.java nix drin man muss die Methoden aus der ITable in die Table java implementieren und vervollständigen

- public Object put
- public Object get
- public boolean containsKey
- public Object remove
- public Object[] keys()

rest ist in der Table.java vorgegeben

genauso bei der Addressbook.java

es ist bei beiden nur das grundgerüst vorgegeben das der Test ausgeführt werden kann aber halt die Methoden komplett noch fehlen und somit fehlermeldungen erscheinen


----------



## The_S (24. Apr 2007)

Gut, so kommen wir schon ein Stück weiter ... auf was wird denn getestet?


----------



## Naeva (24. Apr 2007)

das hier ist das test file


```
import java.util.Arrays;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;


public class TableTest extends TestCase {
    /*
     * ACCEPTS_NULL = true: null ist als key erlaubt.
     *              = false: null-keys erzeugen NullPointerException.
     */
    private static final boolean ACCEPTS_NULL = true;

    /**
     * Diese Methode legt fest, welche Tests durchgeführt werden.
     * Wenn man einzelne Tests abschalten will, muss man nur die
     * entsprechende Zeile auskommentieren.
     * 


     * Wenn man immer die vollständige Ausführung aller Tests haben
     * will, sollte man die Methode suite komplett entfernen.
     */
    public static Test suite() {
        TestSuite t = new TestSuite();
        t.addTest(new TableTest("testConstructor"));
        t.addTest(new TableTest("testOnePutGet"));
        t.addTest(new TableTest("testOverwriting"));
        t.addTest(new TableTest("testRemove"));
        t.addTest(new TableTest("testNullKey"));
        t.addTest(new TableTest("testNullValue"));
        t.addTest(new TableTest("testKeys"));
        t.addTest(new TableTest("testRandomly"));
        return t;
    }
    
    /**
     * Konstructor.
     * Der Konsttruktor wird nur wegen der vorangehenden Methode
     * <code>suite</code> genötigt.
     * 
     * @param sName der auszuführenden Testmethode.
     */
    public TableTest(String testMethod) {
        super(testMethod);
    }
    
    /*
     * Hiermit wird der Belastungstest gesteuert. Die Zahl 1000 ist keine
     * feste Größe, die im Programm berücksichtigt werden darf! Sie könnte
     * z.B. auch 10 Millionen betragen. 
     */
    protected static final int RANDOM_TESTS = 1000;
    
    /*
     * Ein paar Hilfsobjekte.
     */
    protected static final TestKey K1 = new TestKey(177);
    protected static final TestKey K2 = new TestKey(233);
    protected static final TestKey K3 = new TestKey(1235);

    /*
     * Variable für das Testobjekt.
     */
    protected ITable t;

    /**
     * Vorbereitungsarbeiten.
     */
    public void setUp() {
        t = new Table();
        TestKey.clearTotalCompares();
        K1.clearCompares();
        K2.clearCompares();
        K3.clearCompares();
    }

    /**
     * Verlangt, dass ein gerade konstruiertes Objekt, leer ist.
     * Es dürfen keine Daten gefunden werden.
     */
    public void testConstructor() {
        assertEquals("Tabelle muss leer sein", 0, t.size());
        assertFalse("bei leerer Tabelle darf containsKey nichts finden",
            t.containsKey(K1));
    }

    /**
     * Verlangt, dass sich ein einzelnes Schlüssel-Wert-Paar
     * eintragen und wiederfinden lässt. Zusätzlich wird
     * verlangt, dass nicht unnötig viele Vergleiche
     * stattfinden.
     */
    public void testOnePutGet() {
        t.put(K1, K2);
        assertEquals("size() muss nach einem put gleich 1 sein,", 1, t.size());
        assertTrue("containsKey findet das eingetragene Objekt nicht", 
            t.containsKey(K1));
        assertSame("es wird ein falsches Objekt zurückgegeben", 
            K2, t.get(K1));
        assertFalse("contains findet einen nicht vorhandenen Schlüssel", 
            t.containsKey(K2));
        assertNull("wenn nichts gefunden, muss get null zurückgeben",
            t.get(K2));
        int compares = TestKey.getTotalCompares();
        assertTrue("Es wurden 4 Vergleiche erwartet, aber "+ compares +
            " gezählt", 4 >= compares);
    }

    /**
     * Verlangt, dass ein bereits vorhandener Eintrag mit
     * einem neuen Wert überschrieben wird.
     */
    public void testOverwriting() {
        t.put(K1, K2);
        assertSame("das eingetragene Objekt kommt nicht wieder zurück",
           K2, t.get(K1));
        t.put(K1, K3);
        assertSame("beim Überschreiben darf kein neues Objekt angelegt werden",
            K3, t.get(K1));
        assertTrue("zuviele Vergleiche!", 3 >= K1.getCompares());
        assertEquals("Überschreiben darf nicht die Anzahl erhöhen",
            1, t.size());
    }

    /**
     * Verlangt, dass Elemente richtig entfernt werden.
     * Bei dem Aufruf muss der vorhergehende Wert oder
     * <code>null</code> zurückgegeben werden.
     * Es ist kein Fehler, ein nicht vorhandens Element zu
     * entfernen.
     */
    public void testRemove() {
        assertNull("es muss null zurückgegeben werden", t.remove(K1));
        t.put(K1, "x");
        t.put(K2, "a");
        t.put(K3, K1);
        assertEquals("der alte Wert war a", "a", t.remove(K2));
        assertNull("der Schlüssel wurde wohl nicht entfernt", t.remove(K2));
        assertEquals("die Anzahl wurde nicht auf 2 erniedrigt", 2, t.size());
        assertTrue("andere Werte wurden mitgelöscht", t.containsKey(K1));
        assertFalse("der Wert wurde nicht richtig entfernt", t.containsKey(K2));
        assertTrue("andere Werte wurden mitgelöscht", t.containsKey(K3));
        t.put(K2, "x");
        assertEquals("es wird nicht mehr der richtige Wert gefunden",
            "x", t.remove(K1));
        assertEquals("es wird nicht mehr der richtige Wert gefunden",
            "x", t.remove(K2));
        assertSame("es wird nicht mehr der richtige Wert gefunden",
            K1, t.remove(K3));
        assertEquals("die Tabelle müsste leer sein", 0, t.size());
    }

    /**
     * Verlangt, dass die Tabelle mit <code>null</code> Argumenten für
     * Key und Value richtig umgeht. <code>null</code> wird hierbei
     * als gültiger und eindeutiger Schlüssel angesehen.
     */
    public void testNullKey() {
        if (ACCEPTS_NULL) {
            t.put(null, "");
            assertEquals("ein null-Key soll einen Eintrag erlauben",
                1, t.size());
            assertTrue("der null-Key wird nicht gefunden",
                t.containsKey(null));
            assertEquals("es wird der falsche Inhalt zu null zurückgegeben",
                "", t.get(null));
            assertEquals("es wird ein falscher Vorgängerwert zurückgegeben",
                "", t.put(null, "x"));
            assertEquals("Löschen von null funktioniert nicht",
                "x", t.remove(null));
            assertEquals("Löschen von null funktioniert nicht", 0, t.size());
        }
        else {
            String message = "null müsste NullPointerException erzeugen";
            try {
                t.put(null, "");
                fail(message);
            }
            catch (NullPointerException expected) {
                /* this shall happen */
            }
            try {
                t.get(null);
                fail(message);
            }
            catch (NullPointerException expected) {
                /* this shall happen */
            }
            try {
                t.containsKey(null);
                fail(message);
            }
            catch (NullPointerException expected) {
                /* this shall happen */
            }
            try {
                t.remove(null);
                fail(message);
            }
            catch (NullPointerException expected) {
                /* this shall happen */
            }
        }
    }

    /**
     * Verlangt, dass die Tabelle mit <code>null</code> Argumenten für
     * Value richtig umgeht.
     */
    public void testNullValue() {
        t.put("", null);
        assertEquals("ein leerer String mit null-Wert wird falsch behandelt",
            1, t.size());
        assertTrue("contains-Test funktioniert nicht mit null-Wert",
            t.containsKey(""));
        assertNull("die Rückgabe müsste null sein", t.get(""));
    }
    
    /**
     * Testet ob die Rückgabe von keys() wirklich ein
     * Feld mit genau allen Schlüsseln ist.
     */
    public void testKeys() {
        t.put(K1, "x");
        t.put(K2, "a");
        t.put(K3, K1);
        t.put("a", "");
        t.put("b", "");
        Object[] keys = t.keys();
        int nKeys = keys.length;
        assertEquals("keys enthält zu wenig Schlüssel: "+
            nKeys +" anstelle von 5", 5, nKeys);
        int count = 0;
        for (int i = 0; i < t.size(); i++) {
            assertTrue("keys gibt nicht vorhandenen Schlüssel zurück",
                t.containsKey(keys[i]));
            if (keys[i].equals(K1)) count++;
            if (keys[i].equals(K2)) count++;
            if (keys[i].equals(K3)) count++;
            if (keys[i].equals("a")) count++;
            if (keys[i].equals("b")) count++;
        }
        assertEquals("es wurden nicht alle Schlüssel kopiert", 5, count);
    }

    /**
     * Testet eine großer Anzahl von Operationen.
     * Damit soll vor allem die Speicherverwaltung 
     * getestet werden.
     */
    public void testRandomly() {
        int putCount = 0;
        Double keys[] = new Double[RANDOM_TESTS];
        for (int i = 0; i < RANDOM_TESTS; i++) {
            Double key = new Double(Math.random());
            Object oldValue = t.put(key, new Integer(i));
            if (oldValue == null)
                keys[putCount++] = key;
        }
        assertEquals(putCount, t.size());
        Object[] tKeys = t.keys();
        assertEquals(putCount, tKeys.length);
        Arrays.sort(keys);
        Arrays.sort(tKeys);
        assertTrue(Arrays.equals(keys, tKeys));
        for (int i = 0; i < putCount; i++) {
            assertTrue(t.containsKey(keys[i]));
            t.remove(keys[i]);
        }
        assertEquals(0, t.size());
        assertEquals(0, t.keys().length);
    }
}
```


----------



## The_S (24. Apr 2007)

Du kannst mir auch einfach sagen, was welche Methode machen soll, dann muss ich mich nicht in noch mehr Klassen reindenken ...


----------



## Naeva (24. Apr 2007)

Table.java

public Object put = Trägt ein Objekt unter einem Suchbegriff ein. Wenn der Suchbegriff bereits vorhanden, wird die zugehörige Objektreferenz überschrieben und das vorher dort gespeicherte Objekt wird zurückgegeben. Wenn bisher unter dem Schlüssel kein Objekt gespeichert war, wird <code>null</code> zurückgegeben.

public Object get = Gibt das unter einem Suchbegriff gespeicherte Objekt zurück

public boolean containsKey = Stellt fest, ob der Suchschlüssel in der Tabelle eingetragen ist.

public Object remove = Entfernt den Eintrag zu dem angegebenen Suchschlüssel.Wenn kein Eintrag zu dem Schlüssel gefunden wird, wird <code>null</code> zurückgegeben.

public Object[] keys()  = Gibt ein Feld mit allen Suchschlüsseln zurück. 

das sollen die Methoden der Table.java können, laut der Test.java sind diese beiden wohl noch nicht 100% richtig


```
public Object put(Object key, Object value)  {
      if(key==null) throw(new NullPointerException());
      int index=getIndex(key);
      if (index!=-1) { //Key exists
        return data[index].setValue(value);
        }
      else { //New Entry
        if(size>=data.length) { //data full, expand array
          Entry[] datatmp=new Entry[size*2];
          for(int i=0;i<data.length;i++)
          datatmp[i]=data[i];
          data=datatmp;
          }
        data[size]=new Entry(key,value);
        size++;
        return null;
        }
      }
```

anscheinend zuviele Schleifen

und es wird nicht überschrieben laut dem test, so wie ich es sehe


Bei der Addressbook.java

public void addAddress = Fügt eine Email-Adresse in das Verzeichnis ein
public IAddress getAddress = Sucht nach den Adressdaten
Sucht nach den Adressdaten = Überprüft ob der Kurzname bereits als Suchschlüssel verwendet wurde
public void remove = Entfernt Adressdaten aus dem Adressbuch


----------



## The_S (24. Apr 2007)

Warum verwendest du keine HashMap? In deinem Codeausschnitt ist eine einzige Schleife, also können wohl schlecht zuviele Schleifen verwendet worden sein. Was ist Entry für eine Klasse?


----------



## Naeva (24. Apr 2007)

HashMap????

Und laut dem Test File
junit.framework.AssertionFailedError: Es wurden 4 Vergleiche erwartet, aber 14 gezählt 
sind es doch zuviele vergleiche ???


----------



## The_S (24. Apr 2007)

woher soll ich wissen, was ein "vergleich" ist?

Ähm, bevor wir hier weiter diskutieren, auf welchem Niveau befinden wir uns gerade/seit ihr? Ich glaub nämlich so langsam, dass ich dich ein wenig überschätzt habe ...


----------



## Gast (24. Apr 2007)

Studium erstes Semester Java


----------



## The_S (24. Apr 2007)

Das erklärt natürlich einiges ...

eine HashMap ist im Prinzip sowas wie deine Klasse "Tabelle". Kannst dir die Klasse mal anschauen.


----------

