문제

나는 그것을 볼 수있다 Collections.unmodifiableSet 주어진 세트의 수정할 수없는보기를 반환하지만 왜 우리가 사용할 수 없는지 이해할 수 없습니다. final 이것을 달성하기위한 수정 자.

내 이해로 final 상수를 선언합니다 : 수정할 수없는 것. 따라서 세트가 상수로 선언되면 수정할 수 없습니다. 세트에서 아무것도 제거 할 수없고 아무것도 추가 할 수 없습니다.

왜 우리에게 필요한가? Collections.unmodifiableSet?

도움이 되었습니까?

해결책

final 수정할 수없는 객체 참조를 선언합니다.

private final Foo something = new Foo();

새로운 것을 만듭니다 Foo 그리고 참조를 배치합니다 something. 그 후, 변경할 수 없습니다 something 다른 사례를 가리 킵니다 Foo.

이것은 그렇습니다 ~ 아니다 객체의 내부 상태의 수정을 방지합니다. 나는 여전히 모든 방법을 부를 수 있습니다 Foo 관련 범위에 액세스 할 수 있습니다. 해당 메소드 중 하나 이상이 해당 객체의 내부 상태를 수정하면 final 그것을 막지 않습니다.

따라서 다음은 다음과 같습니다.

private final Set<String> fixed = new HashSet<String>();

하다 ~ 아니다 a Set 추가 할 수 없거나 다른 방식으로 변경할 수 없습니다. 그것은 단지 그것을 의미합니다 fixed 해당 인스턴스 만 참조 할 것입니다.

대조적으로 : 수행 :

private Set<String> fixed = Collections.unmodifiableSet( new HashSet<String>() );

a의 인스턴스를 만듭니다 Set 던질 것입니다 UnsupportedOperationException 전화를 시도하는 경우 fixed.add() 또는 fixed.remove(), 예를 들어 - 객체 자체는 내부 상태를 보호하고 수정되지 않도록합니다.

완전성을 위해 :

private final Set<String> fixed = Collections.unmodifiableSet( new HashSet<String>() );

a의 인스턴스를 만듭니다 Set 내부 상태가 변경 될 수 없으며 fixed 해당 세트의 인스턴스 만 지적합니다.

그 이유 final 프리미티브의 상수를 생성하는 데 사용될 수 있습니다. 값을 변경할 수 없다는 사실에 기초합니다. 기억 fixed 위는 단지 참조 일뿐입니다 - 변경할 수없는 주소가 포함 된 변수입니다. 글쎄, 프리미티브의 경우, 예를 들어

private final int ANSWER = 42;

의 가치 ANSWER 그게 42입니다 ANSWER 변경할 수 없습니다. 값 42 만 있으면됩니다.

모든 줄을 흐리게하는 예는 다음과 같습니다.

private final String QUESTION = "The ultimate question";

위의 규칙에 따라 QUESTION 인스턴스의 주소를 포함합니다 String "궁극적 인 질문"을 나타내며 그 주소는 변경할 수 없습니다. 여기서 기억해야 할 것은 그 것입니다 String 그 자체는 불변입니다 - 당신은 String 그것을 변경하고 그렇지 않으면 그렇게 할 작업 (예 : replace, substring, 등) 완전히 다른 인스턴스에 대한 참조를 반환합니다. String.

다른 팁

final 이를 보장합니다 참조 변수를 나타내는 객체에 따라 변경할 수 없습니다. 객체의 인스턴스와 그 돌연변이에 대해서는 아무것도하지 않습니다.

final Set s = new Set(); 할 수없는 것을 보장합니다 s = new Set(); 다시. 설정을 수정할 수 없게 만들지는 않습니다. 처음에는 아무것도 추가 할 수 없었습니다. 그래서 그것을 명확하게하기 위해 final 변수에만 영향을줍니다 참조 참조가 가리키는 객체가 아닙니다.

다음을 수행 할 수 있습니다.

final List<String> l = new ArrayList<String>();
l.add("hello");
l.add("world");
l.remove(0);

그러나 나는 이것을 할 수 없다.

l = new ArrayList<String>();

다시 final 변수 L이 무엇을 가리키는 지 수정할 수 없습니다.

컬렉션 컨테이너 스레드를 안전하게 만들려면 다음 세 가지 중 하나를 수행해야합니다.

java.util.Collections.syncronizedXXX();

또는

java.util.Collections.unmodifiableXXX();

또는 적절한 용기 중 하나를 사용하십시오 java.util.concurrency.* package.

내가 가지고 있다면 Person 대상과 그랬습니다 final Person p = new Person("me"); 재 할당 할 수 없다는 것을 의미합니다 p 다른 사람을 가리키는 것 Person 물체. 나는 여전히 할 수 있습니다 p.setFirstName("you");

상황을 혼란스럽게하는 것은 바로 그 것입니다

final int PI = 3.14;
final String greeting = "Hello World!";

보입니다 const C ++에서, 실제로 그들이 가리키는 물체가 본질적으로 불변/지정할 수없는 경우. 객체의 내부 상태를 변경할 수있는 뮤지토 방법이있는 컨테이너 또는 물체는 const 그냥 그 참조 그 대상들에게 final 그리고 재 할당 할 수 없습니다 참조 다른 대상.

final 그렇지 않음 (C ++ -Style) const. C ++와 달리 Java는 가지고 있지 않습니다 const-메트로 드 또는 그와 비슷한 것, 그리고 객체를 변경할 수있는 메소드는 final 참조.

Collections.unmodifiable* 해당 컬렉션의 읽기 전용을 시행하는 래퍼입니다.

그만큼 Collections.unmodifiableSet(Set<? extends T>) 원본 세트에서 래퍼를 만듭니다. 이 래퍼 세트는 수정할 수 없습니다. 그러나 여전히 원래 세트를 수정할 수 있습니다.

예시:

 Set<String> actualSet=new HashSet<String>(); //Creating set

일부 요소 추가

actualSet.add("aaa");
actualSet.add("bbb");

추가 요소 인쇄

System.out.println(actualSet);   //[aaa, bbb]

actualSet 수정할 수없는 세트로 및 새로운 참조에 할당됩니다 (wrapperSet).

Set<String> wrapperSet=Collections.unmodifiableSet(orginalSet);

Wrapperset을 인쇄하십시오. 그래서 그것은 가질 것입니다 actualSet 가치

System.out.println(wrapperSet);   //[aaa, bbb]

하나의 요소를 제거/추가하려고합니다 wrapperSet.

wrapperSet.remove("aaa");   //UnSupportedOperationException 

하나 더 요소를 추가하십시오 actualSet

    actualSet .add("ccc");

인쇄 actualSet 그리고 wrapperSet. 두 세트 값은 모두 동일합니다. 따라서 실제 설정에 요소를 추가/제거하면 변경 사항이 래퍼 세트에도 반영됩니다.

    System.out.println(actualSet);  //[aaa, ccc, bbb]
    System.out.println(wrapperSet);  // [aaa, ccc, bbb]

용법:

이것 Collections.unmodifiableSet(Set<? extends T>) 모든 객체의 세트 getter 메소드 수정을 방지하는 데 사용됩니다. 말하자

public class Department{

    private Set<User> users=new HashSet<User>();

    public Set<User> getUsers(){
        return Collections.unmodifiableSet(users); 
    }
}

우리가 할 수 있고 할 수 없다고 요약하십시오.

준비:

private Set<String> words = new HashSet<>(Arrays.asList("existing word"));

참조로 최종

private final Set<String> words = new HashSet<>();

~할 수 있다:

words.add("new word");

캔트:

words = new HashSet<>(); //compilation error

참조로 최종 및 컬렉션별로 수정할 수 없습니다.

개인 최종 세트 단어 = collections.unmodifiableSet (단어);

~할 수 있다:

String word = words.iterator().next();

캔트:

words = new HashSet<>(); // compilation error
words.add("new word"); // runtime error UnsupportedOperationException

참조로 최종 및 컬렉션으로 수집 할 수 없지만 컬렉션의 객체로 상호 상호.

하지만 컬렉션이있는 경우 상호간의 개체 해당 객체의 내부 상태를 변경할 수 있습니다.

 class A {
       public int a; //mutable field. I can change it after initialization
       public A(int a) {this.a = a;}
     }

 private final Set<A> set = Collections.unmodifiableSet(Arrays.asList(new A(25)));

아직도 할 수 없습니다

set = new HashSet<>(); // compilation error
set.add(new A(777)); // runtime error UnsupportedOperationException

하지만 할수있다

 A custom = words.iterator().next(); //here custom.a = 25;
 custom.a = 777; //here first element of **final, unmodifible** collection 
    //was changed from 25 to 777
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top