Skip to content

Instantly share code, notes, and snippets.

@andirady
Last active August 29, 2025 09:50
Show Gist options
  • Select an option

  • Save andirady/7605fbef601d8ca77d027f4ea30d0c6b to your computer and use it in GitHub Desktop.

Select an option

Save andirady/7605fbef601d8ca77d027f4ea30d0c6b to your computer and use it in GitHub Desktop.
Basic state management in java
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.*;
var x = new State<>(1);
var xSq = x.map(v -> Math.pow(v, 2));
var doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
var body = doc.appendChild(doc.createElement("body"));
body
.appendChild(doc.createElement("div"))
.appendChild(x.map(String::valueOf).bind(doc::createTextNode, Node::setTextContent));
body
.appendChild(doc.createElement("div"))
.appendChild(xSq.map(String::valueOf).bind(doc::createTextNode, Node::setTextContent));
var transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
x.bind(v -> new DOMSource(doc), (it, v) -> {
try {
transformer.transform(it, new StreamResult(System.out));
} catch (Exception e) {
e.printStackTrace();
}
});
import java.util.function.*;
public class State<T> {
private final List<Consumer<T>> consumers = new ArrayList<>();
private T value;
public State(T value) {
this.value = value;
}
public T set(T newValue) {
if (newValue == value || newValue.equals(value)) {
return value;
}
value = newValue;
consumers.forEach(c -> c.accept(value));
return value;
}
public T set(Function<T, T> setter) {
return set(setter.apply(value));
}
/**
* Bind to a view
*/
public <V> V bind(Function<T, V> creator, BiConsumer<V, T> updater) {
V view = creator.apply(value);
consumers.add(v -> updater.accept(view, v));
return view;
}
/**
* Bind to a view
*/
public <V> V bind(Function<T, V> creator, Consumer<T> updater) {
return bind(creator, (view, v) -> updater.accept(v));
}
/**
* Maps to a new type
*/
public <T2> State<T2> map(Function<T, T2> mapper) {
return bind(v -> new State<T2>(mapper.apply(v)), (it, v) -> it.set(mapper.apply(v)));
}
@Override
public String toString() {
return Objects.toString(value);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment