ZetCode

Java Collections.checkedSortedMap 方法

上次修改时间:2025 年 4 月 20 日

Collections.checkedSortedMap 方法是 Java 集合框架的一部分。它返回指定排序映射的动态类型安全视图。此包装器通过在插入期间检查元素类型来确保运行时类型安全。

该方法特别适用于调试和强制类型约束。如果插入了无效类型,它会抛出 ClassCastException。返回的映射保留了原始排序映射的所有属性。

Collections.checkedSortedMap 概述

Collections.checkedSortedMap 为排序映射提供运行时类型检查。它包装现有的 SortedMap 并检查所有添加的元素。方法签名接受映射和两个用于键和值类型的 Class 对象。

返回的视图阻止插入具有错误类型的元素。它有助于及早检测类型违规行为。包装器保留了原始映射的排序顺序及其所有操作。

checkedSortedMap 的基本用法

此示例演示了 checkedSortedMap 的基本用法。我们创建一个 TreeMap 并用类型检查包装它。该示例显示了有效和无效的操作。

BasicCheckedSortedMap.java
package com.zetcode;

import java.util.Collections;
import java.util.SortedMap;
import java.util.TreeMap;

public class BasicCheckedSortedMap {

    public static void main(String[] args) {
        
        // Create original sorted map
        SortedMap<String, Integer> original = new TreeMap<>();
        original.put("Apple", 10);
        original.put("Banana", 20);
        
        // Create type-safe view
        SortedMap<String, Integer> checked = 
            Collections.checkedSortedMap(original, String.class, Integer.class);
        
        // Valid operation
        checked.put("Cherry", 30);
        System.out.println("Valid addition: " + checked);
        
        try {
            // Invalid key type
            checked.put(42, 40);
        } catch (ClassCastException e) {
            System.out.println("Caught invalid key: " + e.getMessage());
        }
        
        try {
            // Invalid value type
            checked.put("Date", "Fifty");
        } catch (ClassCastException e) {
            System.out.println("Caught invalid value: " + e.getMessage());
        }
    }
}

此代码创建一个 TreeMap 并用类型检查包装它。有效操作正常工作,而无效操作则抛出异常。类型检查适用于键和值。

输出显示了成功操作和捕获的异常。这演示了 checkedSortedMap 如何在运行时强制类型安全。

将 checkedSortedMap 与子映射一起使用

checkedSortedMap 适用于所有 SortedMap 操作,包括子映射视图。此示例显示了应用于从已检查映射创建的子映射的类型检查。

CheckedSubmap.java
package com.zetcode;

import java.util.Collections;
import java.util.SortedMap;
import java.util.TreeMap;

public class CheckedSubmap {

    public static void main(String[] args) {
        
        SortedMap<String, Double> original = new TreeMap<>();
        original.put("A", 1.1);
        original.put("B", 2.2);
        original.put("C", 3.3);
        original.put("D", 4.4);
        
        SortedMap<String, Double> checked = 
            Collections.checkedSortedMap(original, String.class, Double.class);
        
        // Create a submap
        SortedMap<String, Double> submap = checked.subMap("B", "D");
        System.out.println("Original submap: " + submap);
        
        // Valid submap operation
        submap.put("C", 3.33);
        System.out.println("After valid update: " + submap);
        
        try {
            // Invalid operation on submap
            submap.put("E", "Five");
        } catch (ClassCastException e) {
            System.out.println("Caught invalid value in submap: " + e.getMessage());
        }
    }
}

此示例演示了类型检查也适用于子映射。我们从已检查的映射创建一个子映射并执行操作。类型安全在子映射视图中得到维护。

输出显示有效操作成功,而无效操作被捕获。这证明了类型检查在派生映射视图中得到保留。

使用自定义对象的 Checked SortedMap

此示例显示了 checkedSortedMap 与自定义对象一起工作。我们定义一个简单的 Product 类并将其用作映射值类型。类型检查确保只能添加有效的产品。

CheckedCustomObjects.java
package com.zetcode;

import java.util.Collections;
import java.util.SortedMap;
import java.util.TreeMap;

class Product {
    private String name;
    private double price;
    
    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }
    
    @Override
    public String toString() {
        return name + " ($" + price + ")";
    }
}

public class CheckedCustomObjects {

    public static void main(String[] args) {
        
        SortedMap<Integer, Product> inventory = new TreeMap<>();
        inventory.put(1001, new Product("Laptop", 999.99));
        inventory.put(1002, new Product("Phone", 699.99));
        
        SortedMap<Integer, Product> checkedInventory = 
            Collections.checkedSortedMap(inventory, Integer.class, Product.class);
        
        // Valid addition
        checkedInventory.put(1003, new Product("Tablet", 399.99));
        System.out.println("Inventory after valid addition:");
        checkedInventory.forEach((k, v) -> System.out.println(k + ": " + v));
        
        try {
            // Invalid value type
            checkedInventory.put(1004, "Monitor");
        } catch (ClassCastException e) {
            System.out.println("\nCaught invalid product: " + e.getMessage());
        }
    }
}

此示例演示了使用自定义对象的类型检查。Product 类实例是我们映射的唯一有效值。已检查的映射阻止插入无效类型。

输出显示了成功添加有效产品以及在尝试添加无效类型时捕获的异常。这确保了使用自定义类的类型安全。

性能注意事项

虽然 checkedSortedMap 提供了运行时类型安全,但它带来了性能成本。此示例通过比较已检查和未检查映射上的操作来演示开销。

CheckedMapPerformance.java
package com.zetcode;

import java.util.Collections;
import java.util.SortedMap;
import java.util.TreeMap;

public class CheckedMapPerformance {

    static final int OPERATIONS = 100000;

    public static void main(String[] args) {
        
        SortedMap<Integer, String> original = new TreeMap<>();
        SortedMap<Integer, String> checked = 
            Collections.checkedSortedMap(original, Integer.class, String.class);
        
        // Test put performance
        long start = System.nanoTime();
        for (int i = 0; i < OPERATIONS; i++) {
            original.put(i, "Value " + i);
        }
        long originalTime = System.nanoTime() - start;
        
        original.clear();
        
        start = System.nanoTime();
        for (int i = 0; i < OPERATIONS; i++) {
            checked.put(i, "Value " + i);
        }
        long checkedTime = System.nanoTime() - start;
        
        System.out.println("Original map put time: " + originalTime / 1e6 + " ms");
        System.out.println("Checked map put time: " + checkedTime / 1e6 + " ms");
        System.out.println("Overhead: " + 
            (100.0 * (checkedTime - originalTime) / originalTime) + "%");
    }
}

此代码衡量了已检查和未检查映射操作之间的性能差异。我们执行大量插入并比较时间。结果显示了运行时类型检查的开销。

输出显示了两种映射类型上操作所花费的时间。百分比显示了类型检查引入的性能开销。

与 Unmodifiable SortedMap 结合使用

checkedSortedMap 可以与其他包装器(如 unmodifiableSortedMap)结合使用。此示例创建一个同时进行类型检查且不可修改的映射。

CheckedUnmodifiableMap.java
package com.zetcode;

import java.util.Collections;
import java.util.SortedMap;
import java.util.TreeMap;

public class CheckedUnmodifiableMap {

    public static void main(String[] args) {
        
        SortedMap<String, Double> original = new TreeMap<>();
        original.put("USD", 1.0);
        original.put("EUR", 0.85);
        original.put("GBP", 0.72);
        
        // Create checked and unmodifiable view
        SortedMap<String, Double> rates = Collections.unmodifiableSortedMap(
            Collections.checkedSortedMap(original, String.class, Double.class));
        
        System.out.println("Exchange rates: " + rates);
        
        try {
            // Attempt modification
            rates.put("JPY", 110.0);
        } catch (UnsupportedOperationException e) {
            System.out.println("Caught modification attempt: " + e.getMessage());
        }
        
        try {
            // Attempt invalid type
            original.put(42, 1.0);
        } catch (ClassCastException e) {
            System.out.println("Caught invalid type: " + e.getMessage());
        }
    }
}

此示例创建一个同时类型安全且不可修改的映射。我们首先应用类型检查包装器,然后使其不可修改。结果是原始映射的安全视图。

输出演示了修改尝试和无效类型插入都被捕获。这显示了如何组合包装器以获得更强的约束。

实际用例:配置验证

此示例演示了 checkedSortedMap 的一个实际用例:验证配置设置。我们确保配置键是字符串,值是特定类型。

ConfigValidation.java
package com.zetcode;

import java.util.Collections;
import java.util.SortedMap;
import java.util.TreeMap;

public class ConfigValidation {

    public static void main(String[] args) {
        
        SortedMap<String, Object> config = new TreeMap<>();
        
        // Create type-safe configuration map
        SortedMap<String, Object> checkedConfig = 
            Collections.checkedSortedMap(config, String.class, Object.class);
        
        // Valid configurations
        checkedConfig.put("timeout", 30);
        checkedConfig.put("retries", 3);
        checkedConfig.put("debug", false);
        checkedConfig.put("username", "admin");
        
        System.out.println("Valid configuration:");
        checkedConfig.forEach((k, v) -> 
            System.out.println(k + ": " + v + " (" + v.getClass().getSimpleName() + ")"));
        
        try {
            // Invalid key type
            checkedConfig.put(42, "invalid");
        } catch (ClassCastException e) {
            System.out.println("\nCaught invalid key: " + e.getMessage());
        }
        
        // Narrower type checking for specific values
        SortedMap<String, Integer> intConfig = 
            Collections.checkedSortedMap(new TreeMap<>(), String.class, Integer.class);
        intConfig.put("port", 8080);
        
        try {
            intConfig.put("port", "80");
        } catch (ClassCastException e) {
            System.out.println("\nCaught invalid port value: " + e.getMessage());
        }
    }
}

此示例显示了 checkedSortedMap 如何验证配置设置。我们首先创建一个具有字符串键的通用配置映射。然后我们演示了对特定配置值的更严格的类型检查。

输出显示了有效的配置和捕获的异常。此模式对于确保应用程序中的配置完整性很有用。

来源

Java Collections.checkedSortedMap 文档

在本教程中,我们深入探讨了 Collections.checkedSortedMap 方法。我们介绍了基本用法、自定义对象、性能和实际应用。此包装器对于在排序映射中强制类型安全很有价值。

作者

我叫 Jan Bodnar,是一位经验丰富的程序员,在该领域拥有多年的经验。我从 2007 年开始撰写编程文章,此后撰写了 1,400 多篇文章和 8 本电子书。凭借超过八年的教学经验,我致力于分享我的知识并帮助他人掌握编程概念。

列出所有Java教程