PHP hates me – eine Set-Klasse

Kommentare gesperrt, weil dieses Posting Spambots magisch anzieht.

Mir ist aufgefallen, daß meine Klasse nicht abfängt wenn man zweimal dasselbe Objekt ins Set setzt. Deshalb ein kleines Update

Nils Langner von PHP hates me hat eine Aufgabe gestellt. Und hier meine spontane Lösung, vom Hirn ins Terminal 🙂

<?php
<div class="moz-text-plain" style="font-family: -moz-fixed; font-size: 13px;" lang="x-western">
<pre>class Foobar {
}

/**
 * @author Matthias Coy
 */
class Set {
    private $set = null;
    private $typ = null;
    private $className = null;

    /**
     * The method to add something to the set. The type of the set is defined by its first entry.
     * @param <type> $something
     * @public
     */
    function push($something) {
        if ($this->set == null) {
            $this->typ = gettype($something);
            $this->set = array();
            array_push($this->set, $something);
            if($this->typ == "object") {
                $class = new ReflectionClass($something);
                $this->className = $class->getName();
                echo "It's a class, with the name: '".$this->className."'\n";
            } else {
                echo "It's something else: '". $this->typ ."'";
            }
        } else {
            $myType = gettype($something);
            if($myType != $this->typ) {
                throw new Exception("Wrong Type, this set is a set of '".$this->typ."'");
            } else {
                if ($myType == "object") {
                    $class = new ReflectionClass($something);
                    if ($this->className != $class->getName()) {
                        throw new Exception("Right Type, but wrong class (is: '".$class->getName()."', should be: '".$this->className."')");
                    }
                    foreach($this->set as $entry) {
                        if ($something === $entry) {
                            throw new Exception('Right Type, but already in Set');
                        }
                    }
                }
                array_push($this->set, $something);
                echo "adding sth. (".$myType.")\n";
            }
        }
    }

    /**
     * Return the last inserted entry of the set.
     *
     * @return <type>
     * @public
     * @throws Exception if set is empty
     */
    function pop() {
        $returnValue = array_pop($this->set);
        if ($returnValue == null) {
            $this->set = null;
            $this->typ = null;
            $this->className = null;
            throw new Exception("Set is not yet defined, please add something first");
        }
        return $returnValue;
    }

    /**
     * Returns the amount of entries in the set
     *
     * @return <type> Entry of the set
     * @public
     */
    function count() {
        return count($this->set);
    }
}

$var1 = new Set();
$var2 = new Foobar();

$mySet = new Set();
$mySet->push($var1);
try {
    // Add something that is different to the types already in the set
    $mySet->push($var2); // throws execption
} catch (Exception $e) {
    print $e->getMessage()."\n";
}
try {
    // Add something which has the right type, but is already inside the set
    $mySet->push($var1); // throws execption
} catch (Exception $e) {
    print $e->getMessage()."\n";
}
while($mySet->count() > 0) {
    $mySet->pop();
}
$mySet->push($var2);
try {
    $mySet->push($var1);
} catch (Exception $e) {
    print $e->getMessage()."\n";
}
/* Output:
It's a class, with the name: 'Set'
Right Type, but wrong class (is: 'Foobar', should be: 'Set')
Right Type, but already in Set
It's a class, with the name: 'Foobar'
Right Type, but wrong class (is: 'Set', should be: 'Foobar')
 */

Java Collection Interface

Java hat ein paar nette Klassen. Und weil ich mir nie merken kann was jetzt der Unterschied zwischen ‚Set‘ und ‚List‘ ist, hier die Erklaerung. Deutsch/Englisch gemischt, zumindest was die Benennung angeht.

  • Collection — Die Wurzel der Collection-Hierarchie. Eine Collection repraesentiert eine Gruppe von Objekten, auch bekannt als seine Elemente. Das Collection Interface ist die gemeinsame Basis aller Unterklassen und wird benutzt um die Collections untereinander kompatibel zu machen. Ausserdem ermoeglich es einen allgemeinen Zugang zu allen Collections. Manche Untertypen erlauben Duplikate, andere nicht. Manche sind sortiert, andere nicht.
  • Set — Eine Collection die keine doppelten Elemente erhalten kann. Am Besten erklaert ist das an einem Pokerblatt, bei dem keine Karte doppelt vorkommt. Ausser jemand schwindelt und betruegt, aber das gehoert hier nicht hin.
  • List — eine sortierte Collection (manchmal Sequenz genannt). Listen koennen Duplikate enthalten. Im Prinzip also eine Menge von Football-Star-Sammelkarten, von denen man auch welche doppelt haben kann. Wer Vector kennt, dem kommt das bekannt vor.
  • Queue — eine Collection die mehrere Elemente beinhalten kann. Uebersetzt ist das eine Warteschlange, was auch die Funktion erklaert. Meistens wird FIFO benutzt (aber nicht zwingenderweise), d.h. das was als erstes reinkommt, kommt auch als erstes wieder raus. Warteschlange am Metzger halt.
  • Map — ein Objekt das eine Schluessel-Wert-Beziehung repraesentiert. Hier sind wieder keine doppelten Eintraege erlaubt. Vergleichbar mit Schluessel-Schloss, jeder Schluessel passt nur in ein Schloss. Gut, mein VW-Schluessel passt auch in den Polo eines bekannten, aber wir sprechen hier nicht von Autos 🙂

Quelle: http://java.sun.com/docs/books/tutorial/collections/interfaces/index.html

UPDATE: Noch eine Entscheidungshilfe als Bild:

Java Collections Entscheidungshilfe
Java Collections Entscheidungshilfe