MST

星途 面试题库

面试题:Java TreeMap定制化有序存储与检索

假设你需要使用Java TreeMap实现一种特殊的有序存储,存储的数据结构为自定义的复杂对象,该对象包含多个属性,要求根据不同的业务场景,可以按照不同的属性组合进行排序存储和检索。请设计一个通用的解决方案,详细说明如何实现自定义排序规则、如何根据不同业务场景切换排序规则,以及在检索时如何高效地根据排序后的结果找到目标数据。
31.2万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试
  1. 自定义排序规则
    • 首先,自定义的复杂对象需要实现Comparable接口,或者创建一个实现Comparator接口的类来定义排序逻辑。
    • 假设自定义对象为ComplexObject,有属性attr1(整型),attr2(字符串型)等。
    • 实现Comparable接口
class ComplexObject implements Comparable<ComplexObject> {
    private int attr1;
    private String attr2;

    public ComplexObject(int attr1, String attr2) {
        this.attr1 = attr1;
        this.attr2 = attr2;
    }

    public int getAttr1() {
        return attr1;
    }

    public String getAttr2() {
        return attr2;
    }

    @Override
    public int compareTo(ComplexObject other) {
        // 按照attr1升序,如果attr1相同则按照attr2字典序升序
        int result = Integer.compare(this.attr1, other.attr1);
        if (result == 0) {
            result = this.attr2.compareTo(other.attr2);
        }
        return result;
    }
}
  • 实现Comparator接口
class CustomComparator implements Comparator<ComplexObject> {
    @Override
    public int compare(ComplexObject o1, ComplexObject o2) {
        // 按照attr2字典序降序,如果attr2相同则按照attr1降序
        int result = o2.getAttr2().compareTo(o1.getAttr2());
        if (result == 0) {
            result = Integer.compare(o2.getAttr1(), o1.getAttr1());
        }
        return result;
    }
}
  1. 根据不同业务场景切换排序规则
    • 可以通过构造函数或者方法来切换排序规则。
    • 通过构造函数切换
import java.util.Comparator;
import java.util.TreeMap;

public class Main {
    public static void main(String[] args) {
        // 使用默认的Comparable排序
        TreeMap<ComplexObject, String> treeMap1 = new TreeMap<>();
        // 使用自定义的Comparator排序
        TreeMap<ComplexObject, String> treeMap2 = new TreeMap<>(new CustomComparator());
    }
}
  • 通过方法切换
import java.util.Comparator;
import java.util.TreeMap;

public class TreeMapManager {
    private TreeMap<ComplexObject, String> treeMap;

    public TreeMapManager() {
        this.treeMap = new TreeMap<>();
    }

    public void setComparator(Comparator<ComplexObject> comparator) {
        this.treeMap = new TreeMap<>(comparator);
    }

    public void put(ComplexObject key, String value) {
        treeMap.put(key, value);
    }

    public String get(ComplexObject key) {
        return treeMap.get(key);
    }
}
  1. 高效检索
    • 精确匹配检索:由于TreeMap是有序的,可以使用get方法直接根据键进行精确检索,时间复杂度为O(log n),其中n是TreeMap中元素的个数。
TreeMap<ComplexObject, String> treeMap = new TreeMap<>();
ComplexObject target = new ComplexObject(1, "test");
String result = treeMap.get(target);
  • 范围检索:如果需要根据排序后的结果进行范围检索,可以使用subMapheadMaptailMap方法。例如,查找attr1大于某个值的所有对象:
ComplexObject start = new ComplexObject(5, "");
TreeMap<ComplexObject, String> subMap = treeMap.tailMap(start);

这些方法返回的视图与原TreeMap共享数据,操作视图会反映到原TreeMap上,并且由于TreeMap的有序性,范围检索的时间复杂度也是O(log n + m),其中m是范围内元素的个数。