>  기사  >  Java  >  Java 클래스 라이브러리-Guava-불변(불변) 컬렉션

Java 클래스 라이브러리-Guava-불변(불변) 컬렉션

黄舟
黄舟원래의
2017-01-19 13:24:201526검색

불변 컬렉션은 이름에서 알 수 있듯이 컬렉션을 수정할 수 없음을 의미합니다. 컬렉션의 데이터 항목은 생성 시 제공되며 수명 주기 동안 변경할 수 없습니다.

불변 객체를 사용하는 이유는 무엇인가요? 불변 객체는 다음과 같은 장점이 있습니다.

1. 신뢰할 수 없는 클라이언트 코드 라이브러리에 사용해도 안전하며, 이러한 객체는 신뢰할 수 없는 클래스 라이브러리에서도 안전하게 사용할 수 있습니다

2 .Thread-safe: immutable 개체는 다중 스레드에서 안전하고 경쟁 조건이 없습니다

  3. 가변성을 지원할 필요가 없으며 공간 및 시간 오버헤드를 절약하려고 노력할 수 있습니다. 모든 불변 컬렉션 구현은 컬렉션이 사용하는 가변 컬렉션보다 낫습니다. 메모리를 더욱 효율적으로 (분석)

4. 상수로 사용할 수 있고 앞으로도 변함없이 유지될 것으로 예상됩니다

불변 객체는 본질적으로 불변이기 때문에 자연스럽게 상수로 사용할 수 있습니다. 불변 객체를 사용하는 것은 좋은 방어 프로그래밍 기술입니다.

JDK에서 불변 컬렉션 구현

JDK에서는 불변 컬렉션을 구현하기 위해 Collections.unmodifyingXXX 시리즈의 메소드를 제공하지만, 먼저 구체적인 예를 살펴보겠습니다.

 

rree
[code]import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Test;

public class ImmutableTest {
    @Test
    public void testJDKImmutable(){                                                                                                                                                                                                                                    
        List<String> list=new ArrayList<String>();                                                                               
        list.add("a");                                                                                                           
        list.add("b");                                                                                                           
        list.add("c");

        System.out.println(list);

        List<String> unmodifiableList=Collections.unmodifiableList(list); 

        System.out.println(unmodifiableList);

        List<String> unmodifiableList1=Collections.unmodifiableList(Arrays.asList("a","b","c")); 
        System.out.println(unmodifiableList1);

        String temp=unmodifiableList.get(1);
        System.out.println("unmodifiableList [0]:"+temp);

        list.add("baby");
        System.out.println("list add a item after list:"+list);
        System.out.println("list add a item after unmodifiableList:"+unmodifiableList);

        unmodifiableList1.add("bb");
        System.out.println("unmodifiableList add a item after list:"+unmodifiableList1);

        unmodifiableList.add("cc");
        System.out.println("unmodifiableList add a item after list:"+unmodifiableList);        
    }
}


 1. 사용하기 불편하고 번거롭습니다. 모든 방어적인 프로그래밍 복사 장소에서 이 방법을 사용해야 합니다.

 2. 안전하지 않습니다. 원본을 참조하는 객체 캡슐화된 컬렉션 클래스의 경우 이러한 메서드에 의해 반환된 컬렉션은 실제로 변경할 수 없습니다.

3. 낮은 효율성: 반환하는 데이터 구조의 본질은 여전히 ​​원래 컬렉션 클래스이기 때문에 동시 수정 확인을 포함한 작업 오버헤드와 해시 테이블의 추가 데이터 공간은 이전 컬렉션 클래스와 동일합니다. 원본 컬렉션 동일합니다.

Guava의 불변 컬렉션

Guava는 JDK의 표준 컬렉션 클래스의 불변 버전에 대한 간단하고 편리한 구현을 제공할 뿐만 아니라 일부 특수 컬렉션 클래스에 대한 Guava 자체의 불변 구현도 제공합니다. 컬렉션 클래스를 수정하고 싶지 않거나 상수 컬렉션 클래스를 만들고 싶다면 변경할 수 없는 컬렉션 클래스를 사용하는 것이 가장 좋은 프로그래밍 방법입니다.

참고: Guava 불변 컬렉션 클래스의 모든 구현은 null 값을 거부합니다. Google 내부 코드를 포괄적으로 조사한 결과 컬렉션 클래스가 5%의 경우에만 null 값을 허용하는 반면 95%의 경우에서는 null 값을 거부하는 것으로 나타났습니다. null 값을 허용하는 컬렉션 클래스가 정말로 필요한 경우 Collections.unmodifyingXXX 사용을 고려할 수 있습니다.

불변 컬렉션 사용 방법:

불변 컬렉션은 다음과 같은 방법으로 생성할 수 있습니다.

1. copyOf 메서드를 사용합니다(예: ImmutableSet.copyOf(set) )

 2. of 메서드를 사용합니다(예: ImmutableSet.of("a", "b", "c") 또는 ImmutableMap.of("a", 1, "b", 2))

 3. Builder 클래스

[code][a, b, c]
[a, b, c]
[a, b, c]
unmodifiableList [0]:b
list add a item after list:[a, b, c, baby]
list add a item after unmodifiableList1:[a, b, c, baby]

"b", "c", "a", "d", "b")를 사용하면 이 컬렉션의 순회 순서는 "a"입니다. , "b" ", "c", "d".

똑똑한 copyOf

ImmutableXXX.copyOf는 적절한 상황에서 요소 복사를 방지합니다. 먼저 특정 세부 사항을 무시하지만 구현은 일반적으로 매우 "지능적"입니다. . 예를 들어

[code]@Test
    public void testGuavaImmutable(){

        List<String> list=new ArrayList<String>();
        list.add("a");
        list.add("b");
        list.add("c");
        System.out.println("list:"+list);

        ImmutableList<String> imlist=ImmutableList.copyOf(list);
        System.out.println("imlist:"+imlist);

        ImmutableList<String> imOflist=ImmutableList.of("peida","jerry","harry");
        System.out.println("imOflist:"+imOflist);

        ImmutableSortedSet<String> imSortList=ImmutableSortedSet.of("a", "b", "c", "a", "d", "b");
        System.out.println("imSortList:"+imSortList);

         list.add("baby");
         System.out.println("list add a item after list:"+list);
         System.out.println("list add a item after imlist:"+imlist);

         ImmutableSet<Color> imColorSet =
               ImmutableSet.<Color>builder()
                   .add(new Color(0, 255, 255))
                   .add(new Color(0, 191, 255))
                   .build();

         System.out.println("imColorSet:"+imColorSet);       
    }
[code]@Test
    public void testCotyOf(){
        ImmutableSet<String> imSet=ImmutableSet.of("peida","jerry","harry","lisa");
        System.out.println("imSet:"+imSet);
        ImmutableList<String> imlist=ImmutableList.copyOf(imSet);
        System.out.println("imlist:"+imlist);
        ImmutableSortedSet<String> imSortSet=ImmutableSortedSet.copyOf(imSet);
        System.out.println("imSortSet:"+imSortSet);

        List<String> list=new ArrayList<String>();
        for(int i=0;i<20;i++){
            list.add(i+"x");
        }
        System.out.println("list:"+list);
        ImmutableList<String> imInfolist=ImmutableList.copyOf(list.subList(2, 18));
        System.out.println("imInfolist:"+imInfolist);
        int imInfolistSize=imInfolist.size();
        System.out.println("imInfolistSize:"+imInfolistSize);
        ImmutableSet<String> imInfoSet=ImmutableSet.copyOf(imInfolist.subList(2, imInfolistSize-3));
        System.out.println("imInfoSet:"+imInfoSet);
    }



이 코드에서 ImmutableList.copyOf(imSet)는 일정한 시간 복잡도로 ImmutableSet의 imSet.asList()를 지능적으로 반환합니다.

일반적으로 ImmutableXXX.copyOf(ImmutableCollection)는 선형 복잡성 복사 작업을 방지합니다. 예를 들어, 다음 상황에서:

이 작업은 캡슐화된 데이터 구조의 지속적인 복잡성 작업을 활용할 수 있습니다. 그러나 예를 들어 ImmutableSet.copyOf(list)는 지속적인 복잡성으로 구현될 수 없습니다.

이로 인해 메모리 누수가 발생하지 않습니다. 예를 들어 ImmutableList imInfolist가 있고 ImmutableList.copyOf(imInfolist.subList(0, 10))를 명시적으로 조작하는 경우입니다. 이 작업은 더 이상 필요하지 않은 hugeList 요소에 대한 참조를 실수로 보유하는 것을 방지합니다.

ImmutableSet.copyOf(myImmutableSortedSet)와 같은 명시적 복사 작업 집합의 의미는 변경되지 않습니다. 왜냐하면 ImmutableSet에서 hashCode() 및 equals()의 의미가 비교기 기반 ImmutableSortedSet와 다르기 때문입니다.

이러한 기능은 방어 프로그래밍의 성능 오버헤드를 최적화하는 데 도움이 됩니다.

asList 메소드

모든 불변 컬렉션은 asList() 형태로 ImmutableList 뷰를 제공합니다. 예를 들어 ImmutableSortedSet에 데이터를 넣으면 sortedSet.asList().get(k)를 호출하여 처음 k개 요소 집합을 가져올 수 있습니다.

반환된 ImmutableList는 실제 복사본이 아닌 지속적인 복잡성 뷰인 경우가 많습니다. 즉, 이 반환된 컬렉션은 일반 목록보다 더 똑똑합니다. 예를 들어 포함과 같은 메서드를 더 효율적으로 구현합니다.

[code]  @Test
    public void testAsList(){
        ImmutableList<String> imList=ImmutableList.of("peida","jerry","harry","lisa","jerry");
        System.out.println("imList:"+imList);
        ImmutableSortedSet<String> imSortList=ImmutableSortedSet.copyOf(imList);
        System.out.println("imSortList:"+imSortList);
        System.out.println("imSortList as list:"+imSortList.asList());
    }
[code]imList:[peida, jerry, harry, lisa, jerry]
imSortList:[harry, jerry, lisa, peida]
imSortList as list:[harry, jerry, lisa, peida]

 Guava集合和不可变对应关系

可变集合类型 可变集合源:JDK or Guava? Guava不可变集合 

Collection JDK ImmutableCollection 

List JDK ImmutableList 

Set JDK ImmutableSet 

SortedSet/NavigableSet JDK ImmutableSortedSet 

Map JDK ImmutableMap 

SortedMap JDK ImmutableSortedMap 

Multiset Guava ImmutableMultiset 

SortedMultiset Guava ImmutableSortedMultiset 

Multimap Guava ImmutableMultimap 

ListMultimap Guava ImmutableListMultimap 

SetMultimap Guava ImmutableSetMultimap 

BiMap Guava ImmutableBiMap 

ClassToInstanceMap Guava ImmutableClassToInstanceMap 

Table Guava ImmutableTable

以上就是Java-类库-Guava-Immutable(不可变)集合的内容,更多相关内容请关注PHP中文网(www.php.cn)!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.