{"id":2286,"date":"2013-09-09T20:03:54","date_gmt":"2013-09-09T18:03:54","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=2286"},"modified":"2013-09-09T20:03:54","modified_gmt":"2013-09-09T18:03:54","slug":"das-oberste-stack-element-duplizieren-2","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2013\/09\/das-oberste-stack-element-duplizieren-2\/","title":{"rendered":"Das oberste Stack-Element duplizieren"},"content":{"rendered":"<p><i>Die Klasse Stack besitzt zwar die Basisfunktionalit\u00e4t, die ein Stapel besitzen sollte, aber auch nicht mehr. Hin und wieder w\u00fcnschen wir uns aber eine Funktion, die das oberste Stack-Element dupliziert, kurz dup(). Allerdings ist das schwerer als gedacht, und das erkl\u00e4rt auch, warum es so eine Methode nicht gibt.<\/i><\/p>\n<p>Bei der Implementierung treten zwei Fragen auf, mit denen zwei v\u00f6llig unterschiedliche L\u00f6sungsans\u00e4tze verbunden sind. Da die Klasse Stack wie die anderen Datenstrukturen auf Objekte ausgelegt ist, m\u00fcssen wir uns dar\u00fcber Klarheit verschaffen, wie das obere Objekt dupliziert werden soll. Soll eine Kopie der Objekt-Referenz neu auf den Stapel gelegt werden oder etwa das gesamte Objekt geklont werden?<\/p>\n<p><b>Die einfache L\u00f6sung<\/b><\/p>\n<p>Die einfachste L\u00f6sung besteht darin, das oberste Objekt einfach mittels der schon vorhandenen Stack-Methoden <b>push()<\/b> und <b>peek()<\/b> draufzulegen. Nehmen wir an, wir haben eine Unterklasse <b>DupStack<\/b>, dann sieht die erste Variante zum Clonen so aus:<\/p>\n<pre>void dup() \/* throws EmptyStackException *\/\n{\n  push( peek() );\n}<\/pre>\n<p><b>peek()<\/b> gibt aber lediglich eine Referenz auf das Objekt zur\u00fcck. Und das anschlie\u00dfende <b>push() <\/b>speichert diese Referenz dann auf dem Stapel. Nehmen wir an, wir haben zwei <b>StringBuffer<\/b>-Objekte auf dem Stapel. Wenn wir nun <b>dup()<\/b> aufrufen und den String \u00e4ndern, der oben auf dem Stapel liegt, so \u00e4ndern wir automatisch das zweite Element gleich mit. Dies ist aber nicht unbedingt beabsichtigt, und wir m\u00fcssen uns Gedanken \u00fcber eine alternative L\u00f6sung machen. Wir sehen, dass <b>dup()<\/b> in der Klasse Stack fehlt, weil seine Implementierung davon abh\u00e4ngt, ob eine Referenz- oder eine Wertsemantik f\u00fcr Kellerelemente gew\u00fcnscht ist.<\/p>\n<p><b>Die kompliziertere L\u00f6sung mit Klonen<\/b><\/p>\n<p>Um das oberste <b>Stack<\/b>-Element zu kopieren, bietet sich die <b>clone()<\/b>-Methode von <b>Object<\/b> an. All die Objekte, die sich klonen lassen, und das sind l\u00e4ngst nicht alle, implementieren das Interface <b>Cloneable<\/b>. Nun lie\u00dfe sich einfach folgern: Wenn das zu duplizierende Objekt ein Exemplar von <b>Cloneable<\/b> ist, dann k\u00f6nnen wir einfach die <b>clone()<\/b>-Methoden aufrufen und das zur\u00fcckgegebene Objekt mittels <b>push()<\/b> auf den Stapel bringen.<\/p>\n<pre>void dup2() throws CloneNotSupportedException\n{\n  try\n  {\n    Object top = peek();\n\n    if ( top instanceof Cloneable )\n      push( top.clone() );\n\n  }\n  catch ( EmptyStackException e ) { }\n}<\/pre>\n<p>Beziehungsweise<\/p>\n<pre>void dup3() throws CloneNotSupportedException \/*, EmptyStackException *\/\n{\n  push( peek().clone() );\n}<\/pre>\n<p>Dies funktioniert f\u00fcr die meisten Objekte, allerdings nicht f\u00fcr Objekte der Klasse <b>Object<\/b>. Denn <b>clone()<\/b> der Klasse <b>Object<\/b> ist <b>protected<\/b> &#8211; wir d\u00fcrfen also von au\u00dfen nicht dran, nur eine Unterklasse und die Klasse selbst. Hier haben wir also zwei Probleme.<\/p>\n<ul>\n<li>Leider l\u00e4sst sich nur mit Aufwand \u00fcberpr\u00fcfen, ob das Objekt auf dem Stapel auch wirklich ein pures <b>Object<\/b> ist, denn alle Objekte sind <b>instanceof<\/b> Object. Gl\u00fccklicherweise gibt es kaum eine Anwendung, wo reine <b>Object<\/b>-Elemente gesichert werden m\u00fcssen. <\/li>\n<li>Was machen wir mit Objekten, die nicht klonbar sind? Leider gibt es f\u00fcr diese Frage keine direkte Antwort. Eine universelle <b>Stack<\/b>-Klasse mit einer uneingeschr\u00e4nkten <b>dup()<\/b>-Methode gibt es nicht. Wir m\u00fcssen als <b>Stack<\/b>-Benutzer festlegen, dass das oberste Element <b>Cloneable<\/b> ist, um zumindest eine eigene Implementierung nutzen zu k\u00f6nnen. Oder wir bleiben dabei, bei nicht klonbaren Objekten doch nur die Referenz zu duplizieren. Das w\u00e4re zumindest f\u00fcr eineindeutige Objekte mit Wertsemantik die ideale L\u00f6sung.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Die Klasse Stack besitzt zwar die Basisfunktionalit\u00e4t, die ein Stapel besitzen sollte, aber auch nicht mehr. Hin und wieder w\u00fcnschen wir uns aber eine Funktion, die das oberste Stack-Element dupliziert, kurz dup(). Allerdings ist das schwerer als gedacht, und das erkl\u00e4rt auch, warum es so eine Methode nicht gibt. Bei der Implementierung treten zwei Fragen [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[1],"tags":[],"class_list":["post-2286","post","type-post","status-publish","format-standard","hentry","category-allgemein"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2286","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=2286"}],"version-history":[{"count":1,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2286\/revisions"}],"predecessor-version":[{"id":2287,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2286\/revisions\/2287"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=2286"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=2286"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=2286"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}