今日のへま
↓のような不変なクラスを
import java.util.HashSet; import java.util.Set; /** * 名前の集合。不変です。 */ class NameSet { private final Set<String> set; /** * コンストラクタ * @param names 名前 */ NameSet( String... names ) { this.set = new HashSet<String>(); for ( String name : names ) { set.add( name ); } } private NameSet( Set<String> set ) { this.set = set; } /** * 名前を追加します。 * @param names 追加する名前 * @return 名前を追加した{@link NameSet} */ NameSet add( String... names ) { HashSet<String> newSet = new HashSet<String>( set ); for ( String name : names ) { newSet.add( name ); } return new NameSet( newSet ); } /** * 名前を削除します。 * @param names 削除する名前 * @return 名前を削除した{@link NameSet} */ NameSet remove( String... names ) { HashSet<String> newSet = new HashSet<String>( set ); for ( String name : names ) { newSet.remove( name ); } return new NameSet( newSet ); } public boolean equals ( Object obj ) { if ( obj == null ) { return false; } if ( obj instanceof NameSet ) { return set == null ? ((NameSet) obj).set == null : set.equals( ((NameSet) obj).set ); } return false; } public int hashCode () { return this.set == null ? 0 : set.hashCode(); } public String toString () { StringBuilder b = new StringBuilder(); for ( String str : set ) { b.append( str ).append( "," ); } return b.toString(); } }
↓のような感じで使ってしまい、ちょっとはまる。
NameSet kittens = new NameSet( "mii", "tora" ); System.out.println( kittens ); // tora,mii, kittens.add( "shiro", "kuro" ); kittens.remove( "tora" ); System.out.println( kittens ); // tora,mii, // あれ?
これ、クラス名やメソッド名が悪いよなー。Collection派生クラスだと思い込んでしまった・・。「and」とか「or」になっていれば迷わなかったかもなー。むー。