Last active
August 29, 2015 13:57
-
-
Save froop/9561953 to your computer and use it in GitHub Desktop.
[Java] 不変コレクション
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 変更不可(イミュータブル)なCollection. | |
* @param <E> Element: Collection要素の型 | |
* @param <C> Collection: Collectionの型 | |
*/ | |
public abstract class ImmutableCollection<E, C extends Collection<E>> | |
implements Iterable<E> { | |
/** Unmodifiable */ | |
private final C raw; | |
public ImmutableCollection(Collection<E> raw) { | |
if (raw == null) { | |
this.raw = createEmpty(); | |
} else { | |
this.raw = toUnmodifiable(copy(raw)); | |
} | |
} | |
public C toRaw() { | |
return copy(raw); | |
} | |
protected abstract C createEmpty(); | |
protected abstract C copy(Collection<E> source); | |
protected abstract C toUnmodifiable(C source); | |
@Override | |
public Iterator<E> iterator() { | |
return raw.iterator(); | |
} | |
public int size() { | |
return raw.size(); | |
} | |
public boolean isEmpty() { | |
return raw.isEmpty(); | |
} | |
public boolean contains(E o) { | |
return raw.contains(o); | |
} | |
@Override | |
public int hashCode() { | |
return raw.hashCode(); | |
} | |
@Override | |
public boolean equals(Object obj) { | |
return (obj instanceof ImmutableCollection) && is(cast(obj)); | |
} | |
@SuppressWarnings("unchecked") | |
private ImmutableCollection<E, C> cast(Object obj) { | |
return (ImmutableCollection<E, C>) obj; | |
} | |
public boolean is(ImmutableCollection<E, C> obj) { | |
return (obj != null) && raw.equals(obj.raw); | |
} | |
@Override | |
public String toString() { | |
return raw.toString(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 変更不可(イミュータブル)なList. | |
* @param <E> Element: List要素の型 | |
*/ | |
public class ImmutableList<E> extends ImmutableCollection<E, List<E>> { | |
public ImmutableList(Collection<E> raw) { | |
super(raw); | |
} | |
@Override | |
protected List<E> createEmpty() { | |
return Collections.emptyList(); | |
} | |
@Override | |
protected List<E> copy(Collection<E> source) { | |
return new ArrayList<E>(source); | |
} | |
@Override | |
protected List<E> toUnmodifiable(List<E> source) { | |
return Collections.unmodifiableList(source); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ImmutableListTest { | |
@Test | |
public void testDefensiveCopyInput() { | |
List<Integer> in = new ArrayList<Integer>(); | |
in.add(0); | |
ImmutableList<Integer> target = new ImmutableList<Integer>(in); | |
in.add(1); | |
Iterator<Integer> it = target.iterator(); | |
assertThat(it.next(), is(0)); | |
assertFalse(it.hasNext()); | |
} | |
@Test | |
public void testDefensiveCopyOutput() { | |
ImmutableList<Integer> target = new ImmutableList<Integer>(Arrays.asList(0)); | |
List<Integer> out = target.toRaw(); | |
out.add(1); | |
Iterator<Integer> it = target.iterator(); | |
assertThat(it.next(), is(0)); | |
assertFalse(it.hasNext()); | |
} | |
@Test | |
public void testSize() { | |
assertThat(new ImmutableList<Integer>(null).size(), is(0)); | |
assertThat(new ImmutableList<Integer>(Arrays.asList(1, 2)).size(), is(2)); | |
} | |
@Test | |
public void testIsEmpty() { | |
assertTrue(new ImmutableList<Integer>(null).isEmpty()); | |
assertFalse(new ImmutableList<Integer>(Arrays.asList(1)).isEmpty()); | |
} | |
@Test | |
public void testContains() { | |
ImmutableList<String> target = new ImmutableList<String>(Arrays.asList("a", "b")); | |
assertTrue(target.contains("a")); | |
assertFalse(target.contains("c")); | |
} | |
@Test | |
public void testIs() { | |
assertTrue( | |
new ImmutableList<String>(Arrays.asList("a", "b")).is( | |
new ImmutableList<String>(Arrays.asList("a", "b")))); | |
assertFalse( | |
new ImmutableList<String>(Arrays.asList("a", "b")).is( | |
new ImmutableList<String>(Arrays.asList("a", "c")))); | |
assertTrue( | |
new ImmutableList<String>(null).is( | |
new ImmutableList<String>(new ArrayList<String>()))); | |
assertFalse( | |
new ImmutableList<String>(null).is(null)); | |
} | |
@Test | |
public void testToString() { | |
assertThat(new ImmutableList<String>(Arrays.asList("a", "b")).toString(), is("[a, b]")); | |
assertThat(new ImmutableList<String>(null).toString(), is("[]")); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Google Guava の Immutable collections を使おう(提案)