package com.github.commonsrdf.dummyimpl;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Stream;

import com.github.commonsrdf.api.BlankNodeOrIRI;
import com.github.commonsrdf.api.Graph;
import com.github.commonsrdf.api.IRI;
import com.github.commonsrdf.api.RDFTerm;
import com.github.commonsrdf.api.Triple;

public class GraphImpl implements Graph {

	protected Set<Triple> triples = new LinkedHashSet<Triple>();

	@Override
	public void add(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
		add(new TripleImpl(subject, predicate, object));

	}

	@Override
	public void add(Triple triple) {
		if (triple == null) {
			throw new NullPointerException("triple can't be null");
		}
		triples.add(triple);
	}

	@Override
	public void clear() {
		triples.clear();
	}

	@Override
	public boolean contains(BlankNodeOrIRI subject, IRI predicate,
			RDFTerm object) {
		return getTriples(subject, predicate, object).findFirst().isPresent();
	}

	@Override
	public boolean contains(Triple triple) {
		if (triple == null) {
			throw new NullPointerException("triple can't be null");
		}
		return triples.contains(triple);
	}

	@Override
	public Stream<? extends Triple> getTriples() {
		return triples.parallelStream();
	}

	@Override
	public Stream<? extends Triple> getTriples(final BlankNodeOrIRI subject,
			final IRI predicate, final RDFTerm object) {
		Predicate<Triple> match = new Predicate<Triple>() {
			@Override
			public boolean test(Triple t) {
				if (subject != null && !t.getSubject().equals(subject)) {
					return false;
				}
				if (predicate != null && !t.getPredicate().equals(predicate)) {
					return false;
				}
				if (object != null && !t.getObject().equals(object)) {
					return false;
				}
				return true;
			}
		};
		return getTriples().filter(match);
	}

	@Override
	public void remove(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) {
		Iterator<? extends Triple> it = getTriples(subject, predicate, object)
				.iterator();
		while (it.hasNext()) {
			it.remove();
		}
	}

	@Override
	public void remove(Triple triple) {
		if (triple == null) {
			throw new NullPointerException("triple can't be null");
		}
		triples.remove(triple);
	}

	@Override
	public long size() {
		return triples.size();
	}

	@Override
	public String toString() {
		// thread-safe StringBuffer as forEach use parallel streams
		final StringBuffer sb = new StringBuffer();
		getTriples().parallel().forEach(t -> sb.append(t.toString() + "\n"));
		return sb.toString();
	}

}

@@ -52,24 +52,25 @@
 va.util.
-Iterator
+ArrayList
 ;%0Aimport
@@ -80,29 +80,24 @@
 va.util.
-LinkedHashSet
+Iterator
 ;%0Aimport
@@ -107,18 +107,19 @@
 va.util.
-Se
+Lis
 t;%0Aimpor
@@ -448,18 +448,19 @@
 otected 
-Se
+Lis
 t%3CTriple
@@ -479,20 +479,16 @@
 new 
-LinkedHashSe
+ArrayLis
 t%3CTr
@@ -1535,24 +1535,133 @@
 Triple t) %7B%0A
+%09%09%09%09// Lacking the requirement for .equals() we have to be silly%0A%09%09%09%09// and test ntriples string equivalance%0A
 %09%09%09%09if (subj
@@ -1663,33 +1663,39 @@
 (subject != null
- 
+%0A%09%09%09%09%09%09
 && !t.getSubject
@@ -1701,22 +1701,65 @@
 t().
-equals(subject
+ntriplesString()%0A%09%09%09%09%09%09%09%09.equals(subject.ntriplesString()
 )) %7B
@@ -1801,33 +1801,39 @@
 redicate != null
- 
+%0A%09%09%09%09%09%09
 && !t.getPredica
@@ -1841,24 +1841,67 @@
 e().
-equals(predicate
+ntriplesString()%0A%09%09%09%09%09%09%09%09.equals(predicate.ntriplesString()
 )) %7B
@@ -1948,17 +1948,23 @@
  != null
- 
+%0A%09%09%09%09%09%09
 && !t.ge
@@ -1977,21 +1977,64 @@
 t().
-equals(object
+ntriplesString()%0A%09%09%09%09%09%09%09%09.equals(object.ntriplesString()
 )) %7B
@@ -2624,70 +2624,8 @@
 ) %7B%0A
-%09%09// thread-safe StringBuffer as forEach use parallel streams%0A
 %09%09fi
@@ -2636,18 +2636,19 @@
 StringBu
-ff
+ild
 er sb = 
@@ -2663,10 +2663,11 @@
 ngBu
-ff
+ild
 er()
@@ -2683,23 +2683,25 @@
 iples().
-paralle
+sequentia
 l().forE
@@ -2724,26 +2724,8 @@
 nd(t
-.toString() + %22%5Cn%22
 ));%0A

Use List as triple store. In filter, check string equivalence.