📜  Java中的不可变集

📅  最后修改于: 2022-05-13 01:55:02.163000             🧑  作者: Mango

Java中的不可变集

  • 顾名思义,这些 Set 是不可变的。
  • 如果尝试添加、删除和更新集合中的元素,我们将遇到 UnsupportedOperationException。
  • ImmutableSet 也不允许空元素。
  • 如果尝试使用 null 元素创建 ImmutableSet,我们将遇到 NullPointerException。如果尝试在集合中添加空元素,我们将遇到 UnsupportedOperationException。
  • 任何不可变集合(Set、Map、List)的一个优点是线程安全。由于它们是不可变的,因此它们会自动成为线程圣人。
  • 注意它是不可变集合,不是不可变对象的集合,所以里面的对象是可以修改的。

在Java中创建 ImmutableSet

  • 在 Guava 中使用 copyOf() 方法我们使用现有的 Set 来创建 ImmutableSet。
    // Creating an immutable set using copyOf()
    import java.util.*;
    import com.google.common.collect.ImmutableSet;
    import java.io.*;
      
    class GfG
    {
        public static void main(String args[])
        {
            // creating empty set
            Set s = new HashSet();
            s.add("GeeksforGeeks");
            s.add("Practice");
              
            // An immutable copy of s
            Set is  = ImmutableSet.copyOf(s);
                
            System.out.println(is);
        }
    }
    

    输出 :

    [GeeksforGeeks, Practice]
  • 在 Guava 中使用 Of() 方法
    // Java code illustrating of() method to
    // create a ImmutableSet
    import java.util.*;
    import com.google.common.collect.ImmutableSet;
      
    class GfG
    {
        public static void main(String args[])
        {          
            // non-empty immutable set
            ImmutableSet is = 
                     ImmutableSet.of("ide", "code");
                
            // Lets try adding element in these set
            System.out.println(is);             
        }
    }
    

    输出 :

    [ide, code]
  • 使用Java 9 Factory Of() 方法
    在Java中,如果我们使用 with Set、Map 或 List,就会创建一个不可变集。
    // Java code illustrating of() method to
    // create a ImmutableSet
    import java.util.*;
    import com.google.common.collect.ImmutableSet;
      
    class GfG
    {
        public static void main(String args[])
        {          
            // non-empty immutable set
            Set is = Set.of("ide", "code");
                
            // Let's print the set
            System.out.println(is);             
        }
    }
    

    输出 :

    [ide, code]

如果我们尝试更改 ImmutableSet 会怎样?
它抛出 UnsupportedOperationException

// Java code illustrating of() method
import java.util.*;
  
class GfG
{
    public static void main(String args[])
    {
        // empty immutable set
        Set is1 = Set.of();
            
        // non-empty immutable set
        Set is2 = Set.of("ide", "contribute", "support");
            
        // Lets try adding element in these set
        is1.add(null);
        is2.add("set");             
    }
}

输出 :

Exception in thread "main" java.lang.UnsupportedOperationException
    at com.google.common.collect.ImmutableCollection.add(ImmutableCollection.java:218)
    at ImmutableListDemo.main(Main.java:16)

它与 Collections.unmodifiableSet() 有何不同?
Collections.unmodifiableSet 围绕相同的现有集合创建一个包装器,这样包装器就不能用于修改它。但是我们仍然可以更改原始设置。

// Java program to demonstrate that a set created using
// Collections.unmodifiableSet() can be modified indirectly.
import java.io.*;
import java.util.*;
  
class GFG {
public
    static void main(String[] args)
    {
        Set s = new HashSet();
        s.add("Geeks");
        Set us = Collections.unmodifiableSet(s);
  
        // We change s and the changes reflect in us.
        s.add("Practice");
        s.add("Contribute");
        System.out.println(us);
    }
}
输出:
[Geeks, Practice, Contribute]

如果我们从现有集创建一个 ImmutableSet 并更改现有集,则 Immutable Set 不会更改,因为创建了一个副本。

// Creating an immutable set using copyOf()
// and modifying original set.
import java.util.*;
import com.google.common.collect.ImmutableSet;
import java.io.*;
  
class GfG
{
    public static void main(String args[])
    {
        // creating empty set
        Set s = new HashSet();
        s.add("GeeksforGeeks");
        s.add("Practice");
          
        // An immutable copy of s
        Set is  = ImmutableSet.copyOf(s);
            
        // Now if we change 's', 'is' does not change
        s.add("Contribute");
        System.out.println(is);
    }
}

输出 :

[GeeksforGeeks, Practice]

参考
创建不可变列表、集合和映射