GrowOnlySet implements CrdtSet<ElementType, Set<ElementType>, GrowOnlySet<ElementType>> { @Override public GrowOnlySet<ElementType> merge(GrowOnlySet<ElementType> other) { return new GrowOnlySet<>(this, other); } @SuppressWarnings("unused") /* * Used by SerDe */ private  GrowOnlySet();  GrowOnlySet(Set<ElementType> c);  GrowOnlySet(Collection<ElementType> c);  GrowOnlySet(GrowOnlySet<ElementType> first, GrowOnlySet<ElementType> second); @Override GrowOnlySet<ElementType> merge(GrowOnlySet<ElementType> other); @Override Set<ElementType> value(); @Override GrowOnlySet<ElementType> optimize(); int size(); boolean isEmpty(); boolean contains(Object o); Iterator<ElementType> iterator(); Object[] toArray(); T[] toArray(T[] a); boolean add(ElementType e); boolean remove(Object o); boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends ElementType> c); boolean retainAll(Collection<?> c); boolean removeAll(Collection<?> c); void clear(); @Override String toString(); @Override int hashCode(); @Override boolean equals(Object obj);  }
@SuppressWarnings("rawtypes") @Test public void mergeTest(){ ConcurrentHashMap<String, Crdt> a = new ConcurrentHashMap<>(); GrowOnlySet<String> gset = new GrowOnlySet<>(Arrays.asList("a", "b")); Assert.assertEquals(gset, a.merge("a", gset, new CrdtBiFunctionMerge())); GrowOnlySet<String> over = new GrowOnlySet<>(Arrays.asList("b", "d")); Assert.assertEquals(new GrowOnlySet<>(Arrays.asList("a", "b", "d")), a.merge("a", over, CrdtBiFunctionMerge::applyStatic)); }