summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/data/Identity.java
blob: 72fe68c9520780c17e020af90b0e08451cb4cb3c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package bjc.utils.data;

import java.util.function.Function;
import java.util.function.UnaryOperator;

/**
 * @author ben
 *
 * @param <ContainedType>
 */
/**
 * Simple implementation of IHolder that has no hidden behavior
 *
 * @author ben
 *
 * @param <ContainedType>
 *                The type contained in the holder
 */
public class Identity<ContainedType> implements IHolder<ContainedType> {
	private ContainedType heldValue;

	/**
	 * Create a holder holding null
	 */
	public Identity() {
		heldValue = null;
	}

	/**
	 * Create a holder holding the specified value
	 *
	 * @param value
	 *                The value to hold
	 */
	public Identity(ContainedType value) {
		heldValue = value;
	}

	@Override
	public <BoundType> IHolder<BoundType> bind(Function<ContainedType, IHolder<BoundType>> binder) {
		return binder.apply(heldValue);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		else if (obj == null)
			return false;
		else if (getClass() != obj.getClass()) return false;

		Identity<?> other = (Identity<?>) obj;

		if (heldValue == null) {
			if (other.heldValue != null) return false;
		} else if (!heldValue.equals(other.heldValue)) return false;

		return true;
	}

	@Override
	public int hashCode() {
		final int prime = 31;

		int result = 1;

		int fieldHash = heldValue == null ? 0 : heldValue.hashCode();

		result = prime * result + fieldHash;

		return result;
	}

	@Override
	public <NewType> Function<ContainedType, IHolder<NewType>> lift(Function<ContainedType, NewType> func) {
		return (val) -> {
			return new Identity<>(func.apply(val));
		};
	}

	@Override
	public <MappedType> IHolder<MappedType> map(Function<ContainedType, MappedType> mapper) {
		return new Identity<>(mapper.apply(heldValue));
	}

	@Override
	public String toString() {
		return "holding[v=" + heldValue + "]";
	}

	@Override
	public IHolder<ContainedType> transform(UnaryOperator<ContainedType> transformer) {
		heldValue = transformer.apply(heldValue);

		return this;
	}

	@Override
	public <UnwrappedType> UnwrappedType unwrap(Function<ContainedType, UnwrappedType> unwrapper) {
		return unwrapper.apply(heldValue);
	}

	/**
	 * Create a new identity container.
	 * 
	 * @param val
	 *                The contained value.
	 * 
	 * @return A new identity container.
	 */
	public static <ContainedType> Identity<ContainedType> id(ContainedType val) {
		return new Identity<>(val);
	}

	/**
	 * Create a new empty identity container.
	 * 
	 * @return A new empty identity container.
	 */
	public static <ContainedType> Identity<ContainedType> id() {
		return new Identity<>();
	}
}