Skip to content

Commit b1ac5b5

Browse files
author
nicolaiparlog
committed
Create 'TransformingCollectionBuilder' which creates transforming collections, sets and lists
1 parent 1a31cd7 commit b1ac5b5

File tree

5 files changed

+174
-8
lines changed

5 files changed

+174
-8
lines changed

src/demo/java/org/codefx/libfx/collection/transform/TransformingSetDemo.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@ public class TransformingSetDemo {
3535
*/
3636
public TransformingSetDemo() {
3737
innerSet = new HashSet<>();
38-
transformingSet = new TransformingSet<>(
39-
innerSet,
40-
String.class, this::stringToInteger,
41-
Integer.class, this::integerToString);
38+
transformingSet = TransformingCollectionBuilder
39+
.forInnerAndOuterType(String.class, Integer.class)
40+
.toOuter(this::stringToInteger)
41+
.toInner(this::integerToString)
42+
.transformSet(innerSet);
4243

4344
print("-- Initial state --");
4445
print("\t -> " + innerSet + " ~ " + transformingSet);
@@ -177,10 +178,11 @@ private void breakingInverseFunctions() {
177178

178179
private void typeSafety() {
179180
print("-- Using type tokens to increase type safety --");
180-
Set<Integer> transformingSetWithoutTokens = new TransformingSet<>(
181-
innerSet,
182-
Object.class, this::stringToInteger,
183-
Object.class, this::integerToString);
181+
Set<Integer> transformingSetWithoutTokens = TransformingCollectionBuilder
182+
.<String, Integer> forInnerAndOuterTypeUnknown()
183+
.toOuter(this::stringToInteger)
184+
.toInner(this::integerToString)
185+
.transformSet(innerSet);
184186

185187
print("Insert 0, 1, 2");
186188
transformingSet.add(0);

src/main/java/org/codefx/libfx/collection/transform/TransformingCollection.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
* If the {@link #stream() stream} returned by this collection is told to {@link java.util.stream.Stream#sorted() sort}
2222
* itself, it will do so on the base of the comparator returned by the inner collection's spliterator (e.g. based on the
2323
* natural order of {@code I} if it has one).
24+
* <p>
25+
* {@code TransformingCollection}s are created with a {@link TransformingCollectionBuilder}.
2426
*
2527
* @param <I>
2628
* the inner type, i.e. the type of the elements contained in the wrapped/inner collection
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package org.codefx.libfx.collection.transform;
2+
3+
import java.util.Collection;
4+
import java.util.List;
5+
import java.util.Objects;
6+
import java.util.Set;
7+
import java.util.function.Function;
8+
9+
/**
10+
* Builder for {@link TransformingCollection}s, {@link TransformingSet}s and {@link TransformingList}s.
11+
* <p>
12+
* A builder can be obtained by calling {@link #forInnerAndOuterType(Class, Class) forInnerAndOuterType} or
13+
* {@link #forInnerAndOuterTypeUnknown()}. The building methods {@code transform...} can only be called after
14+
* transformations from inner to outer elements and vice versa have been set.
15+
*
16+
* @param <I>
17+
* the inner type of the created transforming collection, i.e. the type of the elements contained in the
18+
* wrapped/inner collection
19+
* @param <O>
20+
* the outer type of the created transforming collection, i.e. the type of elements appearing to be in the
21+
* created collection
22+
*/
23+
public class TransformingCollectionBuilder<I, O> {
24+
25+
// #begin FIELDS
26+
27+
private final Class<? super O> outerTypeToken;
28+
private final Class<? super I> innerTypeToken;
29+
30+
private Function<? super I, ? extends O> transformToOuter;
31+
private Function<? super O, ? extends I> transformToInner;
32+
33+
// #end FIELDS
34+
35+
// #begin CONSTRUCTION
36+
37+
private TransformingCollectionBuilder(Class<? super I> innerTypeToken, Class<? super O> outerTypeToken) {
38+
Objects.requireNonNull(innerTypeToken, "The argument 'innerTypeToken' must not be null.");
39+
Objects.requireNonNull(outerTypeToken, "The argument 'outerTypeToken' must not be null.");
40+
41+
this.outerTypeToken = outerTypeToken;
42+
this.innerTypeToken = innerTypeToken;
43+
}
44+
45+
/**
46+
* Creates a new builder for the specified inner and outer type.
47+
*
48+
* @param <I>
49+
* the inner type of the created transforming collection, i.e. the type of the elements contained in the
50+
* wrapped/inner collection
51+
* @param <O>
52+
* the outer type of the created transforming collection, i.e. the type of elements appearing to be in
53+
* the created collection
54+
* @param innerTypeToken
55+
* the token for the inner type
56+
* @param outerTypeToken
57+
* the token for the outer type
58+
* @return a new builder
59+
*/
60+
public static <I, O> TransformingCollectionBuilder<I, O> forInnerAndOuterType(
61+
Class<? super I> innerTypeToken, Class<? super O> outerTypeToken) {
62+
return new TransformingCollectionBuilder<>(innerTypeToken, outerTypeToken);
63+
}
64+
65+
/**
66+
* Creates a new builder for unknown inner and outer types.
67+
* <p>
68+
* This is equivalent to calling {@link #forInnerAndOuterType(Class, Class) forInnerAndOuterType(Object.class,
69+
* Object.class)}. To obtain a builder for {@code <I, O>} you will have to call
70+
* {@code TransformingCollectionBuilder.<I, O> forInnerAndOuterTypeUnknown()}.
71+
*
72+
* @param <I>
73+
* the inner type of the created transforming collection, i.e. the type of the elements contained in the
74+
* wrapped/inner collection
75+
* @param <O>
76+
* the outer type of the created transforming collection, i.e. the type of elements appearing to be in
77+
* the created collection
78+
* @return a new builder
79+
*/
80+
public static <I, O> TransformingCollectionBuilder<I, O> forInnerAndOuterTypeUnknown() {
81+
return forInnerAndOuterType(Object.class, Object.class);
82+
}
83+
84+
// #end CONSTRUCTION
85+
86+
// #begin SET FIELDS
87+
88+
/**
89+
* Sets the transformation from inner to outer elements which will be used by the created collection.
90+
*
91+
* @param transformToOuter
92+
* transforms inner to outer elements
93+
* @return this builder
94+
*/
95+
public TransformingCollectionBuilder<I, O> toOuter(Function<? super I, ? extends O> transformToOuter) {
96+
Objects.requireNonNull(transformToOuter, "The argument 'transformToOuter' must not be null.");
97+
98+
this.transformToOuter = transformToOuter;
99+
return this;
100+
}
101+
102+
/**
103+
* Sets the transformation from outer to inner elements which will be used by the created collection.
104+
*
105+
* @param transformToInner
106+
* transforms outer to inner elements
107+
* @return this builder
108+
*/
109+
public TransformingCollectionBuilder<I, O> toInner(Function<? super O, ? extends I> transformToInner) {
110+
Objects.requireNonNull(transformToInner, "The argument 'transformToInner' must not be null.");
111+
112+
this.transformToInner = transformToInner;
113+
return this;
114+
}
115+
116+
// #end SET FIELDS
117+
118+
// #begin BUILD
119+
120+
/**
121+
* Creates a {@link TransformingCollection} which transforms/decorates the specified collection.
122+
*
123+
* @param collection
124+
* the collection to transform; will be the inner collection of the returned transformation
125+
* @return a new {@link TransformingCollection}
126+
*/
127+
public TransformingCollection<I, O> transformCollection(Collection<I> collection) {
128+
return new TransformingCollection<>(
129+
collection, innerTypeToken, outerTypeToken, transformToOuter, transformToInner);
130+
}
131+
132+
/**
133+
* Creates a {@link TransformingSet} which transforms/decorates the specified set.
134+
*
135+
* @param set
136+
* the set to transform; will be the inner set of the returned transformation
137+
* @return a new {@link TransformingSet}
138+
*/
139+
public TransformingSet<I, O> transformSet(Set<I> set) {
140+
return new TransformingSet<>(
141+
set, innerTypeToken, outerTypeToken, transformToOuter, transformToInner);
142+
}
143+
144+
/**
145+
* Creates a {@link TransformingList} which transforms/decorates the specified list.
146+
*
147+
* @param list
148+
* the list to transform; will be the inner list of the returned transformation
149+
* @return a new {@link TransformingList}
150+
*/
151+
public TransformingList<I, O> transformList(List<I> list) {
152+
return new TransformingList<>(
153+
list, innerTypeToken, outerTypeToken, transformToOuter, transformToInner);
154+
}
155+
156+
// #end BUILD
157+
158+
}

src/main/java/org/codefx/libfx/collection/transform/TransformingList.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
* If the {@link #stream() stream} returned by this list is told to {@link java.util.stream.Stream#sorted() sort}
2222
* itself, it will do so on the base of the comparator returned by the inner list's spliterator (e.g. based on the
2323
* natural order of {@code O} if it has one).
24+
* <p>
25+
* {@code TransformingList}s are created with a {@link TransformingCollectionBuilder}.
2426
*
2527
* @param <I>
2628
* the inner type, i.e. the type of the elements contained in the wrapped/inner collection

src/main/java/org/codefx/libfx/collection/transform/TransformingSet.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
* If the {@link #stream() stream} returned by this set is told to {@link java.util.stream.Stream#sorted() sort} itself,
2222
* it will do so on the base of the comparator returned by the inner sets's spliterator (e.g. based on the natural order
2323
* of {@code I} if it has one).
24+
* <p>
25+
* {@code TransformingSet}s are created with a {@link TransformingCollectionBuilder}.
2426
*
2527
* @param <I>
2628
* the inner type, i.e. the type of the elements contained in the wrapped/inner set

0 commit comments

Comments
 (0)