public void testSerializationForConsPStack() { final ConsPStack<String> initialConsPStack = ConsPStack.from(Arrays.asList(ELEMENT1, ELEMENT2, ELEMENT3)); final byte[] serializedConsPStack = serializeToByteArray(initialConsPStack); assertNotNull(serializedConsPStack); assertTrue(serializedConsPStack.length > 0); @SuppressWarnings("unchecked") final ConsPStack<String> deserializedConsPStack = deserializeFromByteArray(serializedConsPStack, ConsPStack.class); assertNotNull(deserializedConsPStack); assertEquals(3, deserializedConsPStack.size()); assertNotSame(initialConsPStack, deserializedConsPStack); assertEquals(ELEMENT1, deserializedConsPStack.get(0)); assertEquals(ELEMENT2, deserializedConsPStack.get(1)); assertEquals(ELEMENT3, deserializedConsPStack.get(2)); }
/** * Construct a Cases instance from a list of Pattern Matching Cases * Will execute sequentially when Match is called. * * @param cases Persistent Stack of cases to build Cases from * @return New Cases instance (sequential) */ public static <T,R,X extends Function<T,R>> Cases<T,R,X> ofList(List<Case<T,R,X>> cases){ return new Cases(cases.stream().map(ConsPStack::singleton) .reduce(ConsPStack.empty(),(acc,next)-> acc.plus(acc.size(),next.get(0))),true); }
/** * Construct a Cases instance from an array Pattern Matching Cases * Will execute sequentially when Match is called. * * @param cazes Array of cases to build Cases instance from * @return New Cases instance (sequential) */ public static <T,R,X extends Function<T,R>> Cases<T,R,X> of(Case<T,R,X>... cazes){ return ofPStack( Stream.of(cazes) .map(ConsPStack::singleton) .reduce(ConsPStack.empty(),(acc,next)-> acc.plus(acc.size(),next.get(0)))); } /**
/** * Filter the Cases with the supplied predicate * * <pre> * cases = Cases.of(Case.of(input->true,input->"hello"),Case.of(input->false,input->"second")) .filter(p-> p.getPredicate().test(10)); assertThat(cases.size(),is(1)); * * </pre> * * * @param predicate to filter out cases * @return New Filtered Cases */ public Cases<T,R,X> filter(Predicate<Case<T,R,X>> predicate) { return withCases(cases.stream().filter(data -> predicate.test(data)).map(ConsPStack::singleton) .reduce(ConsPStack.empty(),(acc, next)-> acc.plus(acc.size(),next.get(0)))); }
/** * Expand each Case into a Cases object allowing 1:Many expansion of Cases * * <pre> * Case<Object,Integer,Function<Object,Integer>> cse = Case.of(input-> input instanceof Person, input -> ((Person)input).getAge()); * * * assertThat(Cases.of(cse).flatMap(c -> Cases.of(c.andThen(Case.of( age-> age<18,s->"minor")), * c.andThen(Case.of( age->age>=18,s->"adult")))).match(new Person("bob",21)).get(),is("adult")); * * * </pre> * * @param mapper Function to map Case instances to Cases instances * @return New Cases aggregated from new mapped Cases instances */ public <T1,R1,X1 extends Function<T1,R1>> Cases<T,R,X> flatMap(Function<Case<T,R,X>, Cases<T1,R1,X1>> mapper) { return this.withCases((PStack)cases.stream() .map(mapper) .flatMap(Cases::sequentialStream) .map(ConsPStack::singleton) .reduce(ConsPStack.empty(),(acc, next)-> acc.plus(acc.size(),next.get(0)))); }
/** * Filter the Cases with the supplied predicate * * <pre> * * cases = Cases.of(Case.of(input->true,input->"hello"),Case.of(input->false,input->"second")) * .filterFunction(fn-> fn.apply(10).equals("second")); * assertThat(cases.size(),is(1)); * * </pre> * * * @param predicate to filter out cases * @return New Filtered Cases */ public Cases<T,R,X> filterFunction(Predicate<Function<T,R>> predicate) { return withCases(cases.stream() .filter(data -> predicate.test(data.getAction())).map(ConsPStack::singleton) .reduce(ConsPStack.empty(),(acc, next)-> acc.plus(acc.size(),next.get(0)))); }
/** * Filter the Cases with the supplied predicate * * <pre> * Cases.of(Case.of(input->true,input->"hello"),Case.of(input->false,input->"second")) .filterPredicate(p-> p.test(10)); assertThat(cases.size(),is(1)); * * </pre> * * * @param predicate to filter out cases * @return New Filtered Cases */ public Cases<T,R,X> filterPredicate(Predicate<Predicate<T>> predicate) { return withCases(cases.stream() .filter(data -> predicate.test(data.getPredicate())).map(ConsPStack::singleton) .reduce(ConsPStack.empty(),(acc, next)-> acc.plus(acc.size(),next.get(0)))); }
/** * Map all Case instances present to a different value * * <pre> * List<String> results = Cases.of(Case.of(input->true,input->"hello"),Case.of(input->false,input->"second")) * .map(cse->Case.of(t->true,input->"prefix_"+cse.getAction().apply(input))).<String>matchMany(10).collect(Collectors.toList()); * * assertThat(results.size(),is(2)); * assertTrue(results.stream().allMatch(s->s.startsWith("prefix_"))); * assertTrue(results.stream().anyMatch(s->s.startsWith("prefix_hello"))); * assertTrue(results.stream().anyMatch(s->s.startsWith("prefix_second"))); * * * </pre> * * * @param mapper Function to map case instances * @return New Cases with new Case instances */ public <T1,R1,X1 extends Function<T1,R1>> Cases<T,R,X> map(Function<Case<T,R,X>, Case<T1,R1,X1>> mapper) { return this.withCases((PStack)cases.stream().map(mapper).map(ConsPStack::singleton) .reduce(ConsPStack.empty(),(acc, next)-> acc.plus(acc.size(),next.get(0)))); } /**
/** * Zip two Streams into pattern Matching Cases * * @param predicates Stream of predicates * @param functions Stream of functions * @return Cases with predicates paired to functions */ public static <T,R,X extends Function<T,R>> Cases<T,R,X> zip(Stream<Predicate<T>> predicates, Stream<X> functions){ return ofPStack(SequenceM.fromIterator(predicates.iterator()) .zip(SequenceM.fromIterator(functions.iterator()),(a,b)->Two.tuple(a,b)) .map(Case::of) .map(ConsPStack::singleton) .reduce(ConsPStack.empty(),(acc, next)-> acc.plus(acc.size(),next.get(0)))); } /**