class KusoString {
public KusoString
(String text
) { this.text = text;
this.hashValue = this.hashCode();
}
private final int hashValue;
@Override
public boolean equals
(Object arg0
) { if ( arg0 == null || !(arg0 instanceof KusoString) )
return false;
KusoString other = (KusoString)arg0;
if ( this.hashValue != 0 && other.hashValue != 0 && this.hashValue != other.hashValue )
return false;
if ( this.text == null && other.text == null )
return true;
if ( this.text == null && other.text != null )
return false;
if ( this.text != null && other.text == null )
return false;
assert this.text != null && other.text != null;
if ( this.text.length() != other.text.length() )
return false;
for ( int i = 0; i < this.text.length(); i++ ) {
if ( this.text.charAt(i) != other.text.charAt(i) )
return false;
}
return true;
}
@Override
public int hashCode() {
return this.text.hashCode();
}
}
class Program {
StringBuilder sb = new StringBuilder();
for ( int i = 0; i < 256 * 1024; i++ )
sb.append('a');
KusoString t1 = new KusoString(sb.toString() + '1');
KusoString t2 = new KusoString(sb.toString() + '1');
KusoString t3 = new KusoString(sb.toString() + '2');
System.
out.
printf("%s\n", t1.
equals(t2
));
System.
out.
printf("ちょっとテスト\n"); test(t1, t2);
System.
out.
printf("全比較したとき\n"); test(t1, t2);
System.
out.
printf("ハッシュ比較で済んだとき\n"); test(t1, t3);
}
private static void test(KusoString t1, KusoString t2) {
final int N = 1000 * 1;
long ts
= System.
currentTimeMillis();
boolean b = false;
for ( int i = 0; i < N; i++ )
b |= t1.equals(t2);
long te
= System.
currentTimeMillis(); System.
out.
printf(" %.1fus\n",
(double)(te
- ts
) / N
* 1000, b
); }
}
CmNsYXNzIEt1c29TdHJpbmcgewogICAgcHVibGljIEt1c29TdHJpbmcoU3RyaW5nIHRleHQpIHsKCQl0aGlzLnRleHQgPSB0ZXh0OwoJCXRoaXMuaGFzaFZhbHVlID0gdGhpcy5oYXNoQ29kZSgpOwoJfQoKCXByaXZhdGUgZmluYWwgaW50IGhhc2hWYWx1ZTsKCXByaXZhdGUgZmluYWwgU3RyaW5nIHRleHQ7CgoJQE92ZXJyaWRlCglwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IGFyZzApIHsKCQlpZiAoIGFyZzAgPT0gbnVsbCB8fCAhKGFyZzAgaW5zdGFuY2VvZiBLdXNvU3RyaW5nKSApCgkJCXJldHVybiBmYWxzZTsKCQlLdXNvU3RyaW5nIG90aGVyID0gKEt1c29TdHJpbmcpYXJnMDsKCgkJaWYgKCB0aGlzLmhhc2hWYWx1ZSAhPSAwICYmIG90aGVyLmhhc2hWYWx1ZSAhPSAwICYmIHRoaXMuaGFzaFZhbHVlICE9IG90aGVyLmhhc2hWYWx1ZSApCgkJCXJldHVybiBmYWxzZTsKCgkJaWYgKCB0aGlzLnRleHQgPT0gbnVsbCAmJiBvdGhlci50ZXh0ID09IG51bGwgKQoJCQlyZXR1cm4gdHJ1ZTsKCQlpZiAoIHRoaXMudGV4dCA9PSBudWxsICYmIG90aGVyLnRleHQgIT0gbnVsbCApCgkJCXJldHVybiBmYWxzZTsKCQlpZiAoIHRoaXMudGV4dCAhPSBudWxsICYmIG90aGVyLnRleHQgPT0gbnVsbCApCgkJCXJldHVybiBmYWxzZTsKCgkJYXNzZXJ0IHRoaXMudGV4dCAhPSBudWxsICYmIG90aGVyLnRleHQgIT0gbnVsbDsKCQlpZiAoIHRoaXMudGV4dC5sZW5ndGgoKSAhPSBvdGhlci50ZXh0Lmxlbmd0aCgpICkKCQkJcmV0dXJuIGZhbHNlOwoKCQlmb3IgKCBpbnQgaSA9IDA7IGkgPCB0aGlzLnRleHQubGVuZ3RoKCk7IGkrKyApIHsKCQkJaWYgKCB0aGlzLnRleHQuY2hhckF0KGkpICE9IG90aGVyLnRleHQuY2hhckF0KGkpICkKCQkJCXJldHVybiBmYWxzZTsKCQl9CgkJCgkJcmV0dXJuIHRydWU7Cgl9CgoJQE92ZXJyaWRlCglwdWJsaWMgaW50IGhhc2hDb2RlKCkgewoJCXJldHVybiB0aGlzLnRleHQuaGFzaENvZGUoKTsKCX0KfQoKY2xhc3MgUHJvZ3JhbSB7CglwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB0aHJvd3MgRXhjZXB0aW9uIHsKCQlTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKCQlmb3IgKCBpbnQgaSA9IDA7IGkgPCAyNTYgKiAxMDI0OyBpKysgKQoJCQlzYi5hcHBlbmQoJ2EnKTsKCQlLdXNvU3RyaW5nIHQxID0gbmV3IEt1c29TdHJpbmcoc2IudG9TdHJpbmcoKSArICcxJyk7CgkJS3Vzb1N0cmluZyB0MiA9IG5ldyBLdXNvU3RyaW5nKHNiLnRvU3RyaW5nKCkgKyAnMScpOwoJCUt1c29TdHJpbmcgdDMgPSBuZXcgS3Vzb1N0cmluZyhzYi50b1N0cmluZygpICsgJzInKTsKCQlTeXN0ZW0ub3V0LnByaW50ZigiJXNcbiIsIHQxLmVxdWFscyh0MikpOwoJCQoJCVN5c3RlbS5vdXQucHJpbnRmKCLjgaHjgofjgaPjgajjg4bjgrnjg4hcbiIpOwoJCXRlc3QodDEsIHQyKTsKCgkJU3lzdGVtLm91dC5wcmludGYoIuWFqOavlOi8g+OBl+OBn+OBqOOBjVxuIik7CgkJdGVzdCh0MSwgdDIpOwoJCVN5c3RlbS5vdXQucHJpbnRmKCLjg4/jg4Pjgrfjg6Xmr5TovIPjgafmuIjjgpPjgaDjgajjgY1cbiIpOwoJCXRlc3QodDEsIHQzKTsKCX0KCglwcml2YXRlIHN0YXRpYyB2b2lkIHRlc3QoS3Vzb1N0cmluZyB0MSwgS3Vzb1N0cmluZyB0MikgewoJCWZpbmFsIGludCBOID0gMTAwMCAqIDE7CgkJbG9uZyB0cyA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwoKCQlib29sZWFuIGIgPSBmYWxzZTsKCQlmb3IgKCBpbnQgaSA9IDA7IGkgPCBOOyBpKysgKQoJCQliIHw9IHQxLmVxdWFscyh0Mik7CgkJCgkJbG9uZyB0ZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwoJCVN5c3RlbS5vdXQucHJpbnRmKCIgICAgJS4xZnVzXG4iLCAoZG91YmxlKSh0ZSAtIHRzKSAvIE4gKiAxMDAwLCBiKTsKCX0KfQoK