# immutable Collections



## Landei (21. Sep 2009)

Welche Bibliotheken kennt ihr, die unveränderliche Collections unterstützen? Gibt es irgendwo einen Vergleich? 

Nur zum Verständnis: Ich meine dabei nicht Collections.unmodifyableList() oder sowas, sondern dass Operationen wie add oder remove zwar unterstützt werden, aber jeweils eine neue unveränderliche Liste usw. zurückliefern.

Bisher habe ich gefunden:

Functional Java
pcollections - Project Hosting on Google Code

Mit Einschränkungen:
google-collections - Project Hosting on Google Code


----------



## byte (21. Sep 2009)

Was meinst Du mit "Einschränkungen" bei Google Collections? Die API bietet alle erdenklichen unveränderbaren Collections (List, Map, Set, MultiSet aka Bag) inkl. Builder zum komfortablen Erzeugen der Collections.


----------



## Landei (21. Sep 2009)

Builder ist genau das Problem. Was nützt mir die unveränderliche Collection am Ende, wenn ich davon keine Collection mit einem Element mehr ableiten kann? Und ich will mir beim Programmieren nicht dauernd überlegen, ob ich jetzt den Builder "zumachen" kann oder nicht. Oder habe ich das Konzept bei Google Collections falsch verstanden?


----------



## bygones (21. Sep 2009)

afaik sind Google Collections auch nicht die was du suchst... ImmutableMap erlaubt einfach keine neues added von werten - es gibt dir nicht eine neue Map mit dem alten und neuen werten.

mir sind leider keine bekannt


----------



## Landei (21. Sep 2009)

Dachte ich mir schon, dass Google Collections nicht das Richtige für mich sind. Aber immerhin habe ich die Wahl zwischen den eher minimalistischen PCollections und der "deluxe"-Variante functional java.


----------



## byte (21. Sep 2009)

Landei hat gesagt.:


> Builder ist genau das Problem. Was nützt mir die unveränderliche Collection am Ende, wenn ich davon keine Collection mit einem Element mehr ableiten kann? Und ich will mir beim Programmieren nicht dauernd überlegen, ob ich jetzt den Builder "zumachen" kann oder nicht. Oder habe ich das Konzept bei Google Collections falsch verstanden?



Dann verstehe ich nicht, was Du unter *immutable *im Kontext einer Collection verstehst!? Die Builder ermöglichen Dir die Konstruktion einer danach nicht mehr veränderbaren Collection.

Was genau willst Du denn danach mit der Collection noch machen? Willst du sie verändern? Dann ist sie doch nicht mehr immutable! :bahnhof: Willst Du eine neue Liste mit ein paar Werten aus der anderen Liste generieren? Dann erzeugst Du halt wieder eine mit dem Builder. ???:L


----------



## Landei (21. Sep 2009)

Oh Mann, ich habe es doch oben schon erklärt. Noch mal ganz von vorn:

Stell dir eine unveränderliche Liste vor. Jemand, der eine Referenz auf diese Liste hält, wird immer nur diese Liste sehen, an ihr wird sich kein Fitzelchen verändern. Trotzdem kann die Liste eine add(E e)-Methode enthalten, die eine *neue* unveränderliche Liste mit dem zusätzlichen Element e zurückgibt. 

Das sind "echte" immutable Collections, wie sie in der funktionalen Programmierung gang und gäbe sind (und nicht dieser unmodifyable Krempel, den uns Sun unterjubeln will).

Ein einfaches Beispiel für sowas habe ich ja schon im Forum gepostet: http://www.java-forum.org/mathematik/88198-mathe-aufteilung-von-muenzen.html#post556705


----------



## ice-breaker (21. Sep 2009)

ich denke mal er will das gleiche wie mit String erreichen.

Ein adden eines Elementes zu einer Liste funktioniert, aber die Liste der er das Element "hinzugefügt" hat, verändert sich nicht, stattdessen gibt die Methode eine neue Liste zurück mit den Elementen aus der alten Liste plus dem neuen.

richtig verstanden Landei?

[OT]für scala?[/OT]


----------



## bygones (21. Sep 2009)

jo

```
Collection<String> c = new ArrayList<String>();
Collection<String> d = c.add("foo");
assertThat(c, not(d));
```
so in etwa... durch das aendern eines objekts erhaelt man ein neues objekt


----------



## Landei (21. Sep 2009)

Nicht für Scala. Scala hat selber prima Collections, und dazu "automatische" Umwandlungen von Java-Collections. Aber auch in Java sind immutable Collections oft nützlich, z.B. wenn man etwas "backtracking-artiges" wie mein obiges Beispiel mit den Münzen, oder Multithreading hat.


----------



## byte (21. Sep 2009)

Landei hat gesagt.:


> Oh Mann, ich habe es doch oben schon erklärt. Noch mal ganz von vorn:
> 
> Stell dir eine unveränderliche Liste vor. Jemand, der eine Referenz auf diese Liste hält, wird immer nur diese Liste sehen, an ihr wird sich kein Fitzelchen verändern. Trotzdem kann die Liste eine add(E e)-Methode enthalten, die eine *neue* unveränderliche Liste mit dem zusätzlichen Element e zurückgibt.
> 
> ...



Verstehe nicht, was daran echter sein soll, als das, was Dir Google Collections bietet. Dir fehlt also einfach eine add()-Methode, die eine neue Collection liefert!? Nichts weiter als syntatic sugar...

Semantisch bietet Google Collections genau das von Dir gewünschte:


```
ImmutableList<String> list1 = ImmutableList.<String>builder().add("10").add("20").build();
ImmutableList<String> list2 = ImmutableList.<String>builder().addAll(list1).add("30").build();
```


----------



## bygones (21. Sep 2009)

byte hat gesagt.:


> Verstehe nicht, was daran echter sein soll, als das, was Dir Google Collections bietet. Dir fehlt also einfach eine add()-Methode, die eine neue Collection liefert!? Nichts weiter als syntatic sugar...
> 
> Semantisch bietet Google Collections genau das von Dir gewünschte:
> 
> ...



naja ist schon n bisschen mehr als syntaktisch sugar meiner Ansicht nach. Man wird "gezwungen" erst andere funktionalitaeten zu nutzen bzw zu kennen. Man arbeitet nicht direkt auf den Collections sondern eben ueber ein Framework


----------



## byte (21. Sep 2009)

ImmutableList implementiert java.util.List. Man bleibt also mit Google Collection komform der Collections API von Sun. Die von Landei gewünschte Syntax hingegen widerspricht der Collections API. 

Aber ob ich nun schreibe 
	
	
	
	





```
list2 = list1.add
```
 oder 
	
	
	
	





```
list2 = builder().addAll(list1).add(foo).build()
```
 ist ziemlich wurscht. Der Unterschied ist rein syntaktisch, die Semantik bleibt die gleiche.


----------



## musiKk (21. Sep 2009)

Hast Du schonmal in den Commons Collections geschaut? Mit "immu" find ich zwar schon nichts mehr im JavaDoc, aber vielleicht nennen die das ja anders.


----------



## Marco13 (21. Sep 2009)

Das wäre der Dunstkreis von UnmodifiableCollection (Commons Collections 3.2.1 API)


----------



## ice-breaker (21. Sep 2009)

nein, nicht das was Landei sucht 
wurde aber auch schon besprochen.


----------



## Landei (21. Sep 2009)

byte hat gesagt.:


> ImmutableList implementiert java.util.List. Man bleibt also mit Google Collection komform der Collections API von Sun. Die von Landei gewünschte Syntax hingegen widerspricht der Collections API.


Das passt nicht mit der Collections-API zusammen! Ketzerei!!!1!!1einself! 

Ganz ehrlich: Mit den Java-Collections lässt sich gut und performant arbeiten (wenn man weiß, was man tut), aber die API ist nun wirklich keine Meisterleistung. Ich kann z.B. einer Liste nicht ansehen, ob sie wachsen oder schrumpfen kann, ob sie unmodifyable ist usw. Oder das Iterator-Pattern: Mangels Closures zwar kaum zu vermeiden (FSM sei dank kann man es wenigstens in einer for-loop verstecken), aber man kann nicht herausfinden, ob remove nun unterstützt wird oder nicht, und es fehlt das analoge Builder-Pattern zum Aufbau einer Collection. Von dem statischen Collections-Monster will ich gar nicht erst sprechen, auch wenn es teilweise der (extrem limitierten) Java-Typinferenz geschulded ist...

[edit]
Übrigens kann man immer(!) eine immutable Datenstruktur performant in eine mutable Datenstruktur "wrappen" (wobei letztere dann collections-konform sein kann)


----------



## byte (22. Sep 2009)

Worum gehts Dir denn nun eigentlich? Denn wenn das jetzt auch zu einem Java ist so kacke Thread mutiert, dann bin ich raus. 

Der Hinweis mit der Collection API ging an bygones, der moniert hat, man würde gegen eine Legacy Library programmieren, was halt bei Google Collections nicht der Fall ist.
Und ansonsten liefert Google Collections semantisch genau das, was Du haben willst.


----------



## Landei (22. Sep 2009)

Ich wollte nur wissen, ob ihr vielleicht Bibliotheken mit immutablen Collections (mit denen man auch vernünftig "weiterarbeiten" kann) kennt, die ich noch nicht kenne. Ich hatte eigentlich nicht gedacht, das dieses Konzept soooo ungewöhnlich und erklärungbedürftig ist, wo derartige Collections doch in vielen Fällen klare Vorteile bieten...

Google Collections - so nützlich sie auch sonst sind - gehen zwar ein Stück weit in die richtige Richtung, sind aber nicht das, was ich suche. Ich brauche ja auch nicht die ganze Zeit mit einem StringBuilder zu hantieren, wenn ich noch irgendwas mit meinem String anstellen will, denn auch String bietet Funktionen wie +, substring, replace usw.


----------



## ice-breaker (22. Sep 2009)

nur zum Verständnis, du meinst doch in etwa sowas oder:

```
public List<T> add(T element) {
  List<T> newLst = this.clone();
  newLst.reallyAddTheElement(element);
  return newLst;
}
```


----------



## Landei (22. Sep 2009)

Ja, so könnte man das auch realisieren.


----------



## byte (22. Sep 2009)

Du versuchst hier, objektorientierte und funktionale Syntax zu vermischen. Ich finde das extrem gefährlich. Vom OO-Standpunkt erwartet jeder, dass nach dem list.add das Element auch in list ist. Das ist der Sinn von OO.

Müsste ich so einen Code warten, würde ich definitiv den Kollegen darauf ansprechen, der sowas fabriziert hat. In funktionalen Sprachen ist die Syntax ok, in der OOP hingegen nicht.


----------



## SlaterB (22. Sep 2009)

dann wäre ja String Anti-OO 
oder zumindest BigDecimal auch mit add-Methode

beide Sichten haben ihre Berechtigung


----------



## bygones (22. Sep 2009)

byte hat gesagt.:


> Du versuchst hier, objektorientierte und funktionale Syntax zu vermischen. Ich finde das extrem gefährlich. Vom OO-Standpunkt erwartet jeder, dass nach dem list.add das Element auch in list ist. Das ist der Sinn von OO.t.


nicht unbedingt,, bei String.substring(0,2) erwartest du auch nicht dass der String sich geändert hat... da die API sagt dass es immutable ist. Wenn dass die Collection API auch tun würde, wäre das klar.


----------



## -MacNuke- (22. Sep 2009)

SlaterB hat gesagt.:


> dann wäre ja String Anti-OO



Äh, wenn ich bei einem StringBuilder "append" aufrufe, dann erwarte ich keinen neuen String  Genausowenig erwarte ich, das bei s = s1 + s2 das Ergebnis plötzlich in s1 steht 



SlaterB hat gesagt.:


> oder zumindest BigDecimal auch mit add-Methode



Dieses add ist aber eine Rechenoperation und keine Collections-Methode  Das geht bei BigDecimal ja nunmal nicht anders, da Java kein Operator-Overloading hat.


----------



## bygones (22. Sep 2009)

-MacNuke- hat gesagt.:


> Äh, wenn ich bei einem StringBuilder "append" aufrufe, dann erwarte ich keinen neuen String  Genausowenig erwarte ich, das bei s = s1 + s2 das Ergebnis plötzlich in s1 steht


es hat ja auch keiner mit einem wort Stringbuilder erwähnt. 

und auch s = s1 + s2 hat keiner erwähnt... bei list1 = list2 + list3 erwarte ich das ergebnis in list1




-MacNuke- hat gesagt.:


> Dieses add ist aber eine Rechenoperation und keine Collections-Methode  Das geht bei BigDecimal ja nunmal nicht anders, da Java kein Operator-Overloading hat.


nur weil es in der momentanen API so ist heisst das nicht dass es a) unmöglich ist b) sinnlos ist


----------



## byte (22. Sep 2009)

bygones hat gesagt.:


> nicht unbedingt,, bei String.substring(0,2) erwartest du auch nicht dass der String sich geändert hat... da die API sagt dass es immutable ist. Wenn dass die Collection API auch tun würde, wäre das klar.



substring() suggeriert ja nicht, dass sich der String verändert. Davon abgesehen, ist String sowieso kein gutes Beispiel, da sie auch als Literale realisiert und somit nicht strikt OO sind.
Davon abgesehen ist es ein Unterschied, ob man nun über Strings spricht, die es per Definition nur immutable gibt oder über Collections, die es in allen erdenklichen Implementierungen gibt.

Für gewöhnlich sehe ich gar nicht, um was für eine Implementierung es sich handelt, wenn ich list.add aufrufe. Ich muss erwarten können, dass sich die Methode so verhält, wie sie im Interface spezifiziert ist (und nicht, wie es irgendeine Implementierung grade mal für richtig hält).


----------



## SlaterB (22. Sep 2009)

das ist klar, wen überhaupt dann muss es sich um einen eigenen Kreis Collections mit neuer Interface-Definition handeln,

und dass man die Implementierung nicht kennt, sondern nur die Interface-Methode verwendet ist das was bygones Gestern, 15:23 meinte,
bei derartiger Interface-Programmierung wäre es nicht denkbar, die fest vorgegebene Klasse ImmutableList eines bestimmen Frameworks aufzurufen


----------

