怎么确保一个集合不能被修改?

用 Collections.unmodifiableList() 方法

想象你有一个装满水果的篮子,这个篮子代表一个 List。你想要确保没有人可以拿走或添加水果到篮子里。你可以使用 Collections.unmodifiableList() 方法,它就像给篮子加了一把锁,使得篮子看起来是开着的,但实际上无法被修改。

import java.util.Collections;
import java.util.ArrayList;
import java.util.List;

public class FruitBasket {
    public static void main(String[] args) {
        // 创建一个装满水果的篮子(ArrayList)
        List<String> fruits = new ArrayList<>();
        fruits.add("苹果");
        fruits.add("香蕉");
        fruits.add("橙子");

        // 将篮子上锁,变成不可修改的篮子
        List<String> unmodifiableFruits = Collections.unmodifiableList(fruits);

        // 尝试修改不可修改的篮子
        // unmodifiableFruits.add("新水果"); // 这行代码会抛出异常
        // unmodifiableFruits.remove("香蕉"); // 这行代码也会抛出异常

        // 你可以查看篮子中的水果,但不能改变它们
        System.out.println("不可修改的篮子中的水果:");
        for (String fruit : unmodifiableFruits) {
            System.out.println(fruit);
        }
    }
}

在这个故事中,unmodifiableFruits 就像是一个只读的篮子,你可以查看里面的水果,但不能添加或移除它们。

用 Collections.unmodifiableSet() 或 Collections.unmodifiableMap() 方法

如果你有一个装满糖果的盒子,这个盒子代表一个 Set,你想要确保没有人可以拿走或添加糖果。你可以使用 Collections.unmodifiableSet() 方法。

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

public class CandyBox {
    public static void main(String[] args) {
        // 创建一个装满糖果的盒子(HashSet)
        Set<String> candies = new HashSet<>();
        candies.add("巧克力");
        candies.add("软糖");
        candies.add("棒棒糖");

        // 将盒子上锁,变成不可修改的盒子
        Set<String> unmodifiableCandies = Collections.unmodifiableSet(candies);

        // 尝试修改不可修改的盒子
        // unmodifiableCandies.add("新糖果"); // 这行代码会抛出异常
        // unmodifiableCandies.remove("软糖"); // 这行代码也会抛出异常

        // 你可以查看盒子中的糖果,但不能改变它们
        System.out.println("不可修改的盒子中的糖果:");
        for (String candy : unmodifiableCandies) {
            System.out.println(candy);
        }
    }
}

如果你有一个装满钥匙的盒子,这个盒子代表一个 Map,你想要确保没有人可以拿走或添加钥匙。你可以使用 Collections.unmodifiableMap() 方法。

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class KeyBox {
    public static void main(String[] args) {
        // 创建一个装满钥匙的盒子(HashMap)
        Map<String, String> keys = new HashMap<>();
        keys.put("家门", "钥匙A");
        keys.put("车门", "钥匙B");
        keys.put("抽屉", "钥匙C");

        // 将盒子上锁,变成不可修改的盒子
        Map<String, String> unmodifiableKeys = Collections.unmodifiableMap(keys);

        // 尝试修改不可修改的盒子
        // unmodifiableKeys.put("新钥匙", "钥匙D"); // 这行代码会抛出异常
        // unmodifiableKeys.remove("车门"); // 这行代码也会抛出异常

        // 你可以查看盒子中的钥匙,但不能改变它们
        System.out.println("不可修改的盒子中的钥匙:");
        for (Map.Entry<String, String> entry : unmodifiableKeys.entrySet()) {
            System.out.println(entry.getKey() + " -> " + entry.getValue());
        }
    }
}

用 Collections.emptySet()Collections.emptyMap()Collections.emptyList()

想象你有一个空的篮子,这个篮子代表一个空的 Set,你想要确保没有人可以拿走或添加水果到篮子里。你可以使用 Collections.emptySet() 方法。

import java.util.Collections;
import java.util.Set;

public class EmptyFruitBasket {
    public static void main(String[] args) {
        // 创建一个空的篮子
        Set<String> emptyFruits = Collections.emptySet();

        // 尝试修改空篮子
        // emptyFruits.add("苹果"); // 这行代码会抛出异常
        // emptyFruits.remove("香蕉"); // 这行代码也会抛出异常

        // 你可以查看篮子是否为空,但不能改变它
        System.out.println("空篮子是否为空:" + emptyFruits.isEmpty());
    }
}

使用 Collections.singleton()

想象你有一个装满巧克力的盒子,这个盒子代表一个 Set,你想要确保这个盒子只有一块巧克力。你可以使用 Collections.singleton() 方法。

import java.util.Collections;
import java.util.Set;

public class ChocolateBox {
    public static void main(String[] args) {
        // 创建一个只有一块巧克力的盒子
        Set<String> chocolate = Collections.singleton("巧克力");

        // 尝试修改盒子
        // chocolate.add("新巧克力"); // 这行代码会抛出异常
        // chocolate.remove("巧克力"); // 这行代码也会抛出异常

        // 你可以查看盒子中的巧克力,但不能改变它们
        System.out.println("只有一块巧克力的盒子中的巧克力:");
        for (String candy : chocolate) {
            System.out.println(candy);
        }
    }
}

使用 Collections.nCopies()

想象你有一个装满相同玩具的箱子,这个箱子代表一个 List,你想要确保这个箱子只有一件玩具。你可以使用 Collections.nCopies() 方法。

import java.util.Collections;
import java.util.List;

public class ToyBox {
    public static void main(String[] args) {
        // 创建一个只有一件玩具的箱子
        List<String> toys = Collections.nCopies(1, "玩具车");

        // 尝试修改箱子
        // toys.add("新玩具"); // 这行代码会抛出异常
        // toys.remove("玩具车"); // 这行代码也会抛出异常

        // 你可以查看箱子中的玩具,但不能改变它们
        System.out.println("只有一件玩具的箱子中的玩具:");
        for (String toy : toys) {
            System.out.println(toy);
        }
    }
}

使用 自定义一个不可变集合

自定义不可变集合意味着你需要创建一个类,这个类将包含一个集合,并且不允许外部代码修改这个集合。为了实现这一点,你需要确保集合的引用是私有的,并且不提供任何修改集合的方法。

下面是一个简单的例子,展示了如何创建一个不可变的 List

import java.util.ArrayList;
import java.util.List;

public final class ImmutableListExample {
    private final List<String> list;

    public ImmutableListExample(List<String> list) {
        // 创建一个不可变的列表,这里使用了Collections.unmodifiableList()来确保列表不可修改
        this.list = Collections.unmodifiableList(new ArrayList<>(list));
    }

    // 提供一个方法来获取列表的副本,但不提供修改列表的方法
    public List<String> getList() {
        return new ArrayList<>(list);
    }

    // 主方法,用于演示
    public static void main(String[] args) {
        List<String> originalList = new ArrayList<>();
        originalList.add("苹果");
        originalList.add("香蕉");
        originalList.add("橙子");

        ImmutableListExample immutableListExample = new ImmutableListExample(originalList);

        // 尝试修改列表
        // immutableListExample.getList().add("新水果"); // 这行代码会抛出异常

        // 你可以查看列表中的水果,但不能改变它们
        System.out.println("不可修改的列表中的水果:");
        for (String fruit : immutableListExample.getList()) {
            System.out.println(fruit);
        }
    }
}

在这个例子中,ImmutableListExample 类有一个私有的 List<String> 类型的成员变量 list。在构造函数中,我们使用 Collections.unmodifiableList() 方法来创建一个不可修改的列表,并将其赋值给 list。这样,外部代码就无法直接修改这个列表了。

我们还提供了一个 getList() 方法,它返回一个列表的副本。这样,外部代码可以读取列表中的元素,但不能修改原始列表。

请注意,虽然我们创建了一个不可修改的列表,但这个列表的元素本身(在这个例子中是字符串)是可以被修改的,因为它们是可变的。如果你想要确保列表中的元素也是不可修改的,你需要确保这些元素本身也是不可变的。

通过这种方式,你可以创建一个自定义的不可变集合,它封装了内部的集合,并且提供了只读的访问方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

warming1112

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值