package com.codepoetics.octarine.records; import org.pcollections.PMap; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; final class HashRecord implements Record { private final PMap<Key<?>, Object> values; HashRecord(PMap<Key<?>, Object> values) { this.values = values; } @Override @SuppressWarnings("unchecked") public <T> Optional<T> get(Key<? extends T> key) { return Optional.ofNullable((T) values.get(key)); } @Override public Set<Key<?>> keys() { return values.keySet(); } @Override public PMap<Key<?>, Object> values() { return values; } private Record with(Map<Key<?>, Object> values) { return new HashRecord(this.values.plusAll(values)); } @Override public boolean containsKey(Key<?> key) { return values.containsKey(key); } @Override public Record with(Value... values) { return with(Stream.of(values).collect(Collectors.toMap(Value::key, Value::value))); } @Override public Record with(Record other) { return with(other.values()); } @Override public Record without(Collection<Key<?>> keys) { return new HashRecord(this.values.minusAll(keys)); } @Override public MutableRecord mutable() { return WrappingMutableRecord.wrap(this); } @Override public Record select(Collection<Key<?>> selectedKeys) { Set<Key<?>> keysToDrop = new HashSet<>(keys()); keysToDrop.removeAll(selectedKeys); return without(keysToDrop); } @Override public String toString() { Stream<String> descriptions = values.entrySet() .stream() .map(e -> String.format("%s: %s", e.getKey().name(), e.getValue())); return "{" + String.join(", ", descriptions.collect(Collectors.toList())) + "}"; } @Override public int hashCode() { return values.hashCode(); } @Override public boolean equals(Object other) { if (other instanceof Record) { return ((Record) other).values().equals(values); } return false; } }