이 질문은 Java의 여러 개념을 다룹니다.
먼저 고유성을 보장하려면 왜 java.util.Set을 사용하지 않는지 묻고 싶습니다.
다음으로, 복제 방법. 복제본이 원래 데이터 구조의 shallow copy 또는 deep copy입니까? Vector API documentation from Oracle을 보면 다음과 같이 알 수 있습니다.
이 벡터의 복제본을 반환합니다. 복사본에는 내부 데이터 배열의 복제본에 대한 참조가 포함되며이 Vector 객체의 원래 내부 데이터 배열에 대한 참조는 포함되지 않습니다.
이렇게 우리는 내부 데이터를 복제하기 때문에 깊은 복사본이 있음을 알 수 있습니다. 이제 오버라이드 된 메소드도 복사합니까? 이것에 대한 빠른 테스트는 네, 그렇습니다.
마지막으로 어떻게 테스트 할 수 있습니까? junit과 같은 단위 테스트 프레임 워크를 사용하는 것이 좋습니다.
package test.good;
import static org.junit.Assert.*;
import java.util.Vector;
import org.junit.Before;
import org.junit.Test;
public class CloneTest {
private Vector<MATIdentifier> matIds;
MATIdentifier id1 = new MATIdentifier("first");
MATIdentifier id2 = new MATIdentifier("second");
MATIdentifier id3 = new MATIdentifier("third");
MATIdentifier idDuplicate = new MATIdentifier("first");
@Before
public void prepare() {
matIds = new Vector<MATIdentifier>() {
@Override
public boolean add(MATIdentifier mi) {
if (this.contains(mi)) {
return false;
}
super.add(mi);
return true;
}
@Override
public boolean contains(Object o) {
if (o instanceof MATIdentifier) {
for (MATIdentifier mi : this) {
if (mi.getIdValue().equals(((MATIdentifier) o).getIdValue())) {
return true;
}
}
}
return false;
}
};
}
private void populateVector(Vector<MATIdentifier> vector) {
vector.add(id1);
vector.add(id2);
vector.add(id3);
}
/**
* Tests that adding new values returns true, and adding duplicates returns
* false, and that the duplicates are not actually added
*/
@Test
public void testDuplicateFails() {
boolean added;
added = matIds.add(id1);
assertTrue(added);
added = matIds.add(id2);
assertTrue(added);
added = matIds.add(idDuplicate);
assertFalse(added);
assertEquals(2, matIds.size());
}
@Test
public void testDeepCopy() {
// Start with by pupulating our customized vector
populateVector(matIds);
assertEquals(3, matIds.size());
// Clone the vector
Vector<MATIdentifier> clone = (Vector<MATIdentifier>) matIds.clone();
assertEquals(3, clone.size());
// remove something from the original
matIds.remove(2);
assertEquals(3, clone.size());
assertEquals(2, matIds.size());
// add something to the original
matIds.add(new MATIdentifier("New Value"));
assertEquals(3, clone.size());
assertEquals(3, matIds.size());
// add a duplicate to the clone, to ensure that the overridden behavior
// is present in the clone
boolean added = clone.add(id1);
assertFalse(added);
}
}
class MATIdentifier {
private String idValue;
public MATIdentifier(String idValue) {
this.idValue = idValue;
}
public String getIdValue() {
return idValue;
}
public void setIdValue(String idValue) {
this.idValue = idValue;
}
}
PS, 그것은 MATIdentifier에 등호 작업을 무시하거나 사용자 정의를 작성하는 것보다 MATIdentifier Comparator를 만드는 중 아마 더 좋은 습관이다 : 다음은 당신의 가정이 정확한지 확인하기 위해이 프레임 워크를 사용하는 방법의 예입니다 Vector에 impl을 포함하고 추가합니다. java.util.Set을 사용하는 것이 좋습니다. 또한 중요한 기능은 테스트하기가 더 어렵 기 때문에 좋은 기능은 아닙니다. 특수화 된 Vector 구현을 계속하기를 원한다면 클래스로 옮겨야합니다.
Java Set을 사용하는 것과는 대조적으로, 사용자 (또는 프로그래머)가 Vector에 MATIdentifier가 아닌 유형이 있는지 확인하려고했는지 알 수있을 것입니다. 형식이 MATIdentifier가 아닌 경우 contains 메서드에 인쇄 또는 로깅 문을 넣을 수 있습니다. –
또한 말했듯이 적어도 java.util.Set에서 equals (Object)를 재정의해야합니다. Set에서 override equals를 추측하는 것은 내 Vector 서브 클래스에서 원하는대로 원하는 기능을 포함하도록 설정합니다. 그래서 내 Set 서브 클래스를 다른 클래스에 두거나, 내부 클래스로 두어야합니다. 맞습니까? –
메모 : http://smallwig.blogspot.com/2007/12/why-does-setcontains-take-object-not-e.html –