Collections.unmodifiableList

Collections.unmodifiableList 是 Java Collections Framework 提供的一个方法,用于创建一个不可修改的视图(unmodifiable view)列表。这个方法返回的列表是对原始列表的一个包装,任何对这个包装列表的修改操作都会抛出 UnsupportedOperationException

使用场景

  • 防止修改 :当你希望一个列表在某个范围内不可修改时,可以使用 Collections.unmodifiableList 来创建一个不可修改的视图。
  • 安全性:在方法返回一个列表时,使用不可修改的视图可以防止调用者修改原始列表,从而提高代码的安全性和稳定性。

示例代码

以下是如何使用 Collections.unmodifiableList 的示例:

java 复制代码
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class UnmodifiableListExample {
    public static void main(String[] args) {
        // 创建一个可修改的列表
        List<String> modifiableList = new ArrayList<>();
        modifiableList.add("Apple");
        modifiableList.add("Banana");
        modifiableList.add("Cherry");

        // 创建一个不可修改的视图列表
        List<String> unmodifiableList = Collections.unmodifiableList(modifiableList);

        // 输出不可修改的列表
        System.out.println("Unmodifiable List: " + unmodifiableList);

        // 尝试修改不可修改的列表(会抛出 UnsupportedOperationException)
        try {
            unmodifiableList.add("Date");
        } catch (UnsupportedOperationException e) {
            System.out.println("Cannot modify unmodifiable list: " + e.getMessage());
        }

        // 修改原始列表
        modifiableList.add("Date");

        // 输出不可修改的列表(会反映原始列表的修改)
        System.out.println("Unmodifiable List after modifying original list: " + unmodifiableList);
    }
}

解释

  1. 创建可修改的列表 :首先创建一个 ArrayList,并添加一些元素。
  2. 创建不可修改的视图列表 :使用 Collections.unmodifiableList 方法创建一个不可修改的视图列表。
  3. 尝试修改不可修改的列表 :尝试对不可修改的列表进行添加操作,会抛出 UnsupportedOperationException
  4. 修改原始列表:修改原始列表后,不可修改的视图列表会反映这些修改,因为它只是对原始列表的一个包装。

注意事项

  • 不可修改的视图Collections.unmodifiableList 返回的列表只是一个视图,原始列表的修改会反映到这个视图中。
  • 线程安全Collections.unmodifiableList 并不保证线程安全。如果需要线程安全的不可修改列表,可以使用 Collections.synchronizedListCollections.unmodifiableList 结合使用。

线程安全示例

如果需要线程安全的不可修改列表,可以这样做:

java 复制代码
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ThreadSafeUnmodifiableListExample {
    public static void main(String[] args) {
        // 创建一个线程安全的可修改列表
        List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());
        synchronizedList.add("Apple");
        synchronizedList.add("Banana");
        synchronizedList.add("Cherry");

        // 创建一个不可修改的视图列表
        List<String> unmodifiableList = Collections.unmodifiableList(synchronizedList);

        // 输出不可修改的列表
        System.out.println("Unmodifiable List: " + unmodifiableList);

        // 尝试修改不可修改的列表(会抛出 UnsupportedOperationException)
        try {
            unmodifiableList.add("Date");
        } catch (UnsupportedOperationException e) {
            System.out.println("Cannot modify unmodifiable list: " + e.getMessage());
        }

        // 修改原始列表
        synchronizedList.add("Date");

        // 输出不可修改的列表(会反映原始列表的修改)
        System.out.println("Unmodifiable List after modifying original list: " + unmodifiableList);
    }
}

通过这种方式,可以确保列表在多线程环境下的安全性,同时防止对列表的修改。

List的拷贝

在 Java 中,有多种方法可以复制一个 List。以下是一些常见的方法:

1. 使用 ArrayList 构造函数

你可以使用 ArrayList 的构造函数来创建一个新的 ArrayList,并将原始列表的元素复制到新的列表中。

java 复制代码
import java.util.ArrayList;
import java.util.List;

public class ListCopyExample {
    public static void main(String[] args) {
        List<String> originalList = new ArrayList<>();
        originalList.add("Apple");
        originalList.add("Banana");
        originalList.add("Cherry");

        // 使用 ArrayList 构造函数复制列表
        List<String> copiedList = new ArrayList<>(originalList);

        // 输出复制的列表
        System.out.println("Copied List: " + copiedList);
    }
}

2. 使用 Collections.copy

Collections.copy 方法可以将一个列表的内容复制到另一个列表中。需要注意的是,目标列表必须有足够的空间来容纳源列表的所有元素。

java 复制代码
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ListCopyExample {
    public static void main(String[] args) {
        List<String> originalList = new ArrayList<>();
        originalList.add("Apple");
        originalList.add("Banana");
        originalList.add("Cherry");

        // 创建一个大小相同的目标列表
        List<String> copiedList = new ArrayList<>(Collections.nCopies(originalList.size(), (String) null));

        // 使用 Collections.copy 复制列表
        Collections.copy(copiedList, originalList);

        // 输出复制的列表
        System.out.println("Copied List: " + copiedList);
    }
}

3. 使用 addAll 方法

你可以使用 addAll 方法将一个列表的所有元素添加到另一个列表中。

java 复制代码
import java.util.ArrayList;
import java.util.List;

public class ListCopyExample {
    public static void main(String[] args) {
        List<String> originalList = new ArrayList<>();
        originalList.add("Apple");
        originalList.add("Banana");
        originalList.add("Cherry");

        // 创建一个新的列表
        List<String> copiedList = new ArrayList<>();

        // 使用 addAll 方法复制列表
        copiedList.addAll(originalList);

        // 输出复制的列表
        System.out.println("Copied List: " + copiedList);
    }
}

4. 使用 streamCollectors.toList

你可以使用 Java 8 的 stream API 和 Collectors.toList 方法来复制一个列表。

java 复制代码
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class ListCopyExample {
    public static void main(String[] args) {
        List<String> originalList = new ArrayList<>();
        originalList.add("Apple");
        originalList.add("Banana");
        originalList.add("Cherry");

        // 使用 stream 和 Collectors.toList 复制列表
        List<String> copiedList = originalList.stream().collect(Collectors.toList());

        // 输出复制的列表
        System.out.println("Copied List: " + copiedList);
    }
}

5. 使用 clone 方法(适用于 ArrayList

如果你使用的是 ArrayList,可以直接使用其 clone 方法来复制列表。

java 复制代码
import java.util.ArrayList;
import java.util.List;

public class ListCopyExample {
    public static void main(String[] args) {
        List<String> originalList = new ArrayList<>();
        originalList.add("Apple");
        originalList.add("Banana");
        originalList.add("Cherry");

        // 使用 clone 方法复制列表
        List<String> copiedList = (List<String>) ((ArrayList<String>) originalList).clone();

        // 输出复制的列表
        System.out.println("Copied List: " + copiedList);
    }
}

总结

以上方法都可以用来复制一个 List,具体选择哪种方法取决于你的需求和使用场景。如果你需要一个简单的、快速的复制,可以使用 ArrayList 构造函数或 addAll 方法。如果你需要更灵活的操作,可以考虑使用 streamCollectors.toList

相关推荐
七夜zippoe几秒前
Java技术未来展望:GraalVM、Quarkus、Helidon等新趋势探讨
java·开发语言·python·quarkus·graaivm·helidon
草莓熊Lotso3 分钟前
【Linux 线程进阶】进程 vs 线程资源划分 + 线程控制全详解
java·linux·运维·服务器·数据库·c++·mysql
ShineWinsu8 分钟前
对于Linux:文件操作以及文件IO的解析
linux·c++·面试·笔试·io·shell·文件操作
-SGlow-8 分钟前
Linux相关概念和易错知识点(52)(基于System V的信号量和消息队列)
linux·运维·服务器
江畔何人初10 分钟前
TCP的三次握手与四次挥手
linux·服务器·网络·网络协议·tcp/ip
m0_7381207211 分钟前
网络安全编程——Python编写基于UDP的主机发现工具(解码IP header)
python·网络协议·tcp/ip·安全·web安全·udp
北冥有羽Victoria15 分钟前
OpenCLI 操作网页 从0到1完整实操指南
vscode·爬虫·python·github·api·ai编程·opencli
handsomestWei17 分钟前
scikit-learn数据预处理模块
python·机器学习·scikit-learn
w_t_y_y21 分钟前
机器学习常用的python包(二)工具箱scikit-learn
python·机器学习·scikit-learn
Trouvaille ~24 分钟前
【MySQL篇】数据库操作:从创建到管理
linux·数据库·mysql·oracle·xshell·ddl