Skip to content

Instantly share code, notes, and snippets.

@monzou
Created October 17, 2011 02:41
Show Gist options
  • Save monzou/1291824 to your computer and use it in GitHub Desktop.
Save monzou/1291824 to your computer and use it in GitHub Desktop.
package hobby;
/**
* 疑似 Option 型です。
*
* @author monzou
* @param <T> 要素の型
*/
public interface Option<T> {
/**
* 値を取得します。
*
* @param defaultValue デフォルト値
* @return 値
*/
T get(T defaultValue);
}
package hobby;
import java.io.Serializable;
import com.google.common.base.Predicate;
/**
* {@link Option} に関するユーティリティです。
*
* @author monzou
*/
public final class Options {
/**
* None のインスタンスを取得します。
*
* @param <T> 値の型
* @return None
*/
@SuppressWarnings("unchecked")
public static <T> Option<T> none() {
return (Option<T>) None.INSTANCE;
}
/**
* Some のインスタンスを生成します。
*
* @param <T> 値の型
* @param value 値
* @return Some
*/
public static <T> Option<T> some(T value) {
return new Some<T>(value);
}
/** None の条件関数 */
public static Predicate<Option<?>> NONE_PREDICATE = new Predicate<Option<?>>() {
/** {@inheritDoc} */
@Override
public boolean apply(Option<?> input) {
return input == None.INSTANCE;
}
};
/** Some の条件関数 */
public static Predicate<Option<?>> SOME_PREDICATE = new Predicate<Option<?>>() {
/** {@inheritDoc} */
@Override
public boolean apply(Option<?> input) {
return Some.class.isAssignableFrom(input.getClass());
}
};
private static enum None implements Option<Object> {
INSTANCE {
/** {@inheritDoc} */
@Override
public Object get(Object defaultValue) {
return defaultValue;
}
/** {@inheritDoc} */
@Override
public String toString() {
return "NONE";
}
};
}
@SuppressWarnings("serial")
private static class Some<T> implements Option<T>, Serializable {
private final T value;
private Some(T value) {
Preconditions.checkNotNull(value, "value must not be null.");
this.value = value;
}
/** {@inheritDoc} */
@Override
public T get(T defaultValue) {
return value;
}
/** {@inheritDoc} */
@Override
public boolean equals(Object obj) {
if (obj instanceof Some<?>) {
return value.equals(((Some<?>) obj).value);
}
return false;
}
/** {@inheritDoc} */
@Override
public int hashCode() {
return value.hashCode();
}
}
private Options() {
}
}
package hobby;
import java.util.Collection;
import java.util.List;
import junit.framework.TestCase;
import org.junit.Test;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
/**
* OptionsTest
*
* @author monzou
*/
public class OptionsTest extends TestCase {
@Test
public void testMatching() {
List<Option<String>> list = Lists.newArrayList();
list.add(Options.some("one"));
list.add(Options.some("two"));
list.add(Options.some("three"));
list.add(Options.<String> none());
list.add(Options.some("four"));
{
Collection<Option<String>> c = Collections2.filter(list, Options.SOME_PREDICATE);
assertEquals(4, c.size());
for (Option<String> op : c) {
assertFalse(op == Options.<String> none());
assertNotNull(op.get(null));
}
}
{
Collection<Option<String>> c = Collections2.filter(list, Options.NONE_PREDICATE);
assertEquals(1, c.size());
for (Option<String> op : c) {
assertTrue(op == Options.<String> none());
assertEquals("hoge", op.get("hoge"));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment