Ja, ich hatte es auch schon gelesen, aber meine Gedanken dazu noch nicht geordnet (und) niedergeschrieben.
Einerseits erscheint es sinnvoll und nahe liegend. An einigen Stellen hatte ich schon die “Dualität” ausgenutzt, die man erahnen kann, z.B. mit einer `Map<Integer, T> asMap(List list)[/inlne].
Andererseits stellen sich dabei einige Fragen, auf verschiedenen Ebenen.
Auf der obersten Ebene steht die Frage, die ich schonmal im anderen Forum unter der Überschrift “Abstraktions-Overkill” gestellt hatte (und der etwas reißerisch oder potentiell negativ klingende Titel soll hier keine Wertung sein ;)). Damals hatte ich angedeutet, dass man praktisch alles, was man schreibt, auf Function
und Set
zurückführen kann. Wie schon in http://forum.byte-welt.net/threads/12534-Mathematische-Sets-in-neco4j angedeutet ist eine Mathematische Menge ja gleichwertig mit einem Prädikat, nämlich dem, das aussagt, ob ein Element in der Menge ist oder nicht. Und ein Prädikat ist eine Function (von T auf boolean
). Wenn man die Vereinigung zweier Mengen beschreiben will, kann man das mit einem Operator, der so gesehen auch nur eine Function<Tuple2<Set<T>, Set<T>>, Set<T>>
ist. Mir ist nicht klar, an welcher Stelle man mit der Abstraktion aufhören soll…
Im krassen Gegensatz zu dieser (übergeordnet-philosophischen) Frage (die ohnehin nie oder zumindest nicht objektiv) beantwortet werden kann, könnte man jetzt gleich die Frage nach der Performance stellen, wenn man immer (z.B. für indizierten Zugriff) aufs Auto(un)boxing zwischen int
und Integer
vertrauen muss - aber sei das erstmal zweitrangig (die JVMs der Zukunft werden das schon richten ;))
Dazwischen liegt aber noch die (erstmal wichtigere) Frage nach der “Konsistenz”, bzw. der Einhaltung des “Principle of Least Astonishment”. Die bezieht sich speziell auf den indizierten Zugriff: Eine NecoIndexedList<V>
extendet NecoCollection<Integer,V>
.
NecoIndexedList<V> list = createListWithSize(3);
V v0 = list.get(0);
V v1 = list.get(1);
V v2 = list.get(2);
NecoIndexedList<V> modifiedList = list.remove(1);
// Welche der folgenden Zeilen liefert eine NoSuchElementException?
V mv0 = modifiedList.get(0);
V mv1 = modifiedList.get(1);
V mv2 = modifiedList.get(2);
// (Unabhängig davon: )
// Welcher der folgenden Ausdrücke ergibt "true"?
boolean b0 = (v0 == mv0);
boolean b1 = (v1 == mv1);
boolean b2 = (v2 == mv2);
boolean b3 = (v2 == mv1); // !?
Nicht, dass man sie nicht beantworten könnte, aber es gibt viele Details, die man da berücksichtigen muss…