Skip to content

Instantly share code, notes, and snippets.

@bmchild
Created August 31, 2015 14:57
Show Gist options
  • Save bmchild/55cdaa65b6e52696c977 to your computer and use it in GitHub Desktop.
Save bmchild/55cdaa65b6e52696c977 to your computer and use it in GitHub Desktop.
A Nonfunctional way of chaining java 8 Predicates together of different generic types.
package com.bmchild.utils;
import java.util.Objects;
import java.util.function.Predicate;
/**
* Non functional way of chaining predicates together
* @author brettchild
*
* @param <T>
*/
public class PredicateChain<T> {
private T objectToTest;
private Predicate<T> predicate;
public PredicateChain(T instanceToTest, Predicate<T> predicate) {
Objects.requireNonNull(instanceToTest);
Objects.requireNonNull(predicate);
this.objectToTest = instanceToTest;
this.predicate = predicate;
}
/**
* Private constructor to create new chains
* @param predicate
*/
private PredicateChain(Predicate<T> predicate) {
Objects.requireNonNull(predicate);
this.predicate = predicate;
}
public Predicate<T> toPredicate() {
return t -> this.test();
}
public boolean test() {
return predicate.test(objectToTest);
}
public PredicateChain<T> and(PredicateChain<?> other) {
Objects.requireNonNull(other);
return new PredicateChain<T>(t -> this.test() && other.test());
}
public PredicateChain<T> or(PredicateChain<?> other) {
Objects.requireNonNull(other);
return new PredicateChain<T>(t -> this.test() || other.test());
}
public PredicateChain<T> negate() {
return new PredicateChain<T>(this.toPredicate().negate());
}
}
package com.bmchild.utils;
import org.junit.Assert;
import org.junit.Test;
public class PredicateChainTest {
private String stringtoTest = "1234567890";
private Integer inttoTest = 99;
private Integer intTwoToTest = 5;
@Test
public void testTest() throws Exception {
PredicateChain<String> isTenCharacters = new PredicateChain<String>(stringtoTest, t -> t.length() == 10);
Assert.assertTrue(isTenCharacters.test());
}
@Test
public void testAnd() throws Exception {
PredicateChain<String> isTenCharacters = new PredicateChain<String>(stringtoTest, t -> t.length() == 10);
PredicateChain<Integer> isLT100 = new PredicateChain<Integer>(inttoTest, i -> i < 100);
Assert.assertTrue(isTenCharacters.and(isLT100).test());
PredicateChain<Integer> isFive = new PredicateChain<Integer>(intTwoToTest, i -> i == 5);
Assert.assertTrue(isTenCharacters.and(isLT100).and(isFive).test());
}
@Test
public void testAnd_FALSE_STRING() throws Exception {
PredicateChain<String> isFiveCharacters = new PredicateChain<>(stringtoTest, t -> t.length() == 5);
PredicateChain<Integer> isLT100 = new PredicateChain<Integer>(inttoTest, i -> i < 100);
Assert.assertFalse(isFiveCharacters.and(isLT100).test());
}
@Test
public void testAnd_FALSE_INT() throws Exception {
PredicateChain<String> isTenCharacters = new PredicateChain<String>(stringtoTest, t -> t.length() == 10);
PredicateChain<Integer> isLT50 = new PredicateChain<Integer>(inttoTest, i -> i < 50);
Assert.assertFalse(isTenCharacters.and(isLT50).test());
}
@Test
public void testOr() throws Exception {
PredicateChain<String> isTenCharacters = new PredicateChain<String>(stringtoTest, t -> t.length() == 10);
PredicateChain<Integer> isLT100 = new PredicateChain<Integer>(inttoTest, i -> i < 100);
Assert.assertTrue(isTenCharacters.or(isLT100).test());
}
@Test
public void testOr_LEFT_SIDE() throws Exception {
PredicateChain<String> isTenCharacters = new PredicateChain<String>(stringtoTest, t -> t.length() == 10);
PredicateChain<Integer> isLt50 = new PredicateChain<Integer>(inttoTest, i -> i < 50);
Assert.assertTrue(isTenCharacters.or(isLt50).test());
}
@Test
public void testOr_RIGHT_SIDE() throws Exception {
PredicateChain<String> is5Characters = new PredicateChain<String>(stringtoTest, t -> t.length() == 5);
PredicateChain<Integer> isLt100 = new PredicateChain<Integer>(inttoTest, i -> i < 100);
Assert.assertTrue(is5Characters.or(isLt100).test());
}
@Test
public void testOr_NEITHER_SIDE() throws Exception {
PredicateChain<String> is5Characters = new PredicateChain<String>(stringtoTest, t -> t.length() == 5);
PredicateChain<Integer> isLt10 = new PredicateChain<Integer>(inttoTest, i -> i < 10);
Assert.assertFalse(is5Characters.or(isLt10).test());
}
@Test
public void testNegate() throws Exception {
PredicateChain<String> isTenCharacters = new PredicateChain<String>(stringtoTest, t -> t.length() == 10).negate();
Assert.assertFalse(isTenCharacters.test());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment