I’d like to claim it is possible to “just use maps” in Java!
This discussion is a follow up on a previous discussion “Just use maps” in Java?.
“just use maps” in Java could be done with:
- Paguro: a Java library that provides an implementation of persistent maps and a version of Clojure’s Transducers
- String maps only (keys are strings, values are arbitrary)
- Specific getters for each type of values to avoid the need for casting objects (in the spirit of what @ericnormand suggested)
Here is an example of how a Data-Oriented programming code snippet could look like in Java
Let’s create a nested map that represents a library catalog data (my favourite example!) via Paguro’s map
and tup
constructors:
var catalog = map(tup("booksByIsbn",
map(tup("978-1779501127",
map(tup("isbn", "978-1779501127"),
tup("title", "Watchmen"),
tup("publicationYear", 1987),
tup("authorIds", vec("alan-moore",
"dave-gibbons")))))),
tup("authorsById",
map(tup("alan-moore",
map(tup("name", "Alan Moore"),
tup("bookIsbns", vec("978-1779501127")))),
tup("dave-gibbons",
map(tup("name", "Dave Gibbons"),
tup("bookIsbns", vec("978-1779501127")))))));
And here is an example of a simple data manipulation code: Calculating the list of the author names:
(See implementation of getAsMapOfMaps
and getAsString
below)
getAsMapOfMaps(catalog, "authorsById")
.values()
.map(author -> getAsString(author, "name"))
.toImList()
// PersistentVector("Alan Moore","Dave Gibbons")
I think that this piece of Java code is quite similar to what we are used to write in Clojure:
(->> catalog
vals
(map #(get % "name"))
(into []))
Now the interesting question is: how the Java community is going to receive an approach like this and to be willing to relax on compile-time type validation in order to gain flexibility.
Could you suggest ways of improving the DOP approach in Java so that it increases the odds of being well-received by the Java community?
Implementation of specific getters:
import org.organicdesign.fp.collections.ImList;
import org.organicdesign.fp.collections.ImMap;
public class SpecificGetters {
// TODO: move to methods in ImMap and ImList
// TODO: Implement getInAs...
// TODO: Implement getAsMapOfLists, getAsNumber, ...
public String getAsString(Map o, Object k) {
return (String)o.get((String)k);
}
public ImMap getAsMap(Map o, Object k) {
return (ImMap)o.get((String)k);
}
public ImMap<String, ImMap> getAsMapOfMaps(ImMap o, Object k) {
return (ImMap<String,ImMap>)o.get((String)k);
}
public ImList getAsList(Map o, Object k) {
return (ImList)o.get((String)k);
}
}