You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

泛型数组二分查找返回前两索引或栈溢出异常问题求助

泛型二分查找(带Comparator)实现方案

嘿,我之前也折腾过这个需求,非泛型的二分查找确实简单,但泛型+Comparator的组合要注意几个关键点,尤其是解耦比较逻辑和保证数组有序性!下面给你一套完整的实现思路和代码,应该能解决你的问题:

核心思路

泛型版本的关键在于不依赖元素自身的Comparable接口,而是通过传入Comparator来定义比较规则,这样就能支持任意类型(包括那些没实现Comparable的自定义类),同时完美兼容Integer、Double、String这些常见类型。另外一定要记住:二分查找的前提是数组已经按照Comparator的规则排好序,否则查找结果会完全错误!

完整代码实现

1. 泛型二分查找工具方法

import java.util.Comparator;
import java.util.Scanner;

public class GenericBinarySearch {
    // 泛型二分查找方法,支持任意类型,依赖Comparator完成比较逻辑
    public static <E> int binarySearch(E[] array, E target, Comparator<? super E> comparator) {
        // 边界检查:避免空指针异常
        if (array == null || comparator == null) {
            throw new IllegalArgumentException("数组或比较器不能为null");
        }
        if (target == null) {
            throw new IllegalArgumentException("目标元素不能为null");
        }

        int low = 0;
        int high = array.length - 1;

        while (low <= high) {
            // 用这种方式计算mid,避免low+high过大导致整数溢出
            int mid = low + (high - low) / 2;
            int compareResult = comparator.compare(array[mid], target);

            if (compareResult == 0) {
                return mid; // 找到目标元素,返回索引
            } else if (compareResult < 0) {
                low = mid + 1; // 目标在右半区间,调整左边界
            } else {
                high = mid - 1; // 目标在左半区间,调整右边界
            }
        }
        return -1; // 遍历完未找到目标,返回-1
    }

2. 用户交互与测试逻辑

接着写主方法,实现你想要的「用户选择类型→生成数组→执行查找」流程:

public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 提示用户选择查找类型
        System.out.println("请选择要查找的数组类型:");
        System.out.println("1. Integer数组");
        System.out.println("2. Double数组");
        System.out.println("3. String数组");
        int choice = scanner.nextInt();
        scanner.nextLine(); // 清除输入缓冲区的换行符

        switch (choice) {
            case 1:
                // 生成预排序的Integer数组
                Integer[] intArray = {1, 3, 5, 7, 9, 11, 13, 15};
                System.out.print("请输入要查找的整数:");
                int targetInt = scanner.nextInt();
                int intResult = binarySearch(intArray, targetInt, Integer::compare);
                printResult(intResult, targetInt);
                break;
            case 2:
                // 生成预排序的Double数组
                Double[] doubleArray = {1.2, 3.4, 5.6, 7.8, 9.0, 11.2};
                System.out.print("请输入要查找的小数:");
                double targetDouble = scanner.nextDouble();
                int doubleResult = binarySearch(doubleArray, targetDouble, Double::compare);
                printResult(doubleResult, targetDouble);
                break;
            case 3:
                // 生成预排序的String数组(按字典序)
                String[] stringArray = {"apple", "banana", "cherry", "date", "elderberry"};
                System.out.print("请输入要查找的字符串:");
                String targetString = scanner.nextLine();
                // 用忽略大小写的比较器,提升用户体验
                int stringResult = binarySearch(stringArray, targetString, String::compareToIgnoreCase);
                printResult(stringResult, targetString);
                break;
            default:
                System.out.println("无效的选择,请重新运行程序!");
        }
        scanner.close();
    }

    // 统一的结果打印方法,复用逻辑
    private static <E> void printResult(int index, E target) {
        if (index != -1) {
            System.out.printf("找到元素 %s,索引为 %d%n", target, index);
        } else {
            System.out.printf("未找到元素 %s%n", target);
        }
    }
}

关键细节说明

  • 泛型通配符:用Comparator<? super E>而非Comparator<E>,这样可以接受更宽泛的比较器(比如元素父类的Comparator),提升代码灵活性。
  • 溢出防护:计算mid时用low + (high - low)/2,避免low+high数值过大时超出int类型范围导致溢出。
  • 健壮性处理:加入了null值判断,避免运行时空指针异常,让代码更稳定。
  • 简化写法:调用时用Integer::compare、String::compareToIgnoreCase这类方法引用,替代繁琐的匿名内部类,代码更简洁易读。

常见问题排查

如果你当前的实现「勉强可用但有问题」,大概率是这几个原因:

  • 数组未按Comparator规则排序:比如String数组用了忽略大小写的比较器,但数组本身是按大小写敏感排序的,会直接导致查找失败。
  • 未处理null值:比如目标元素或数组为null时没有做校验,运行时会抛出异常。
  • 泛型类型不兼容:传入的Comparator类型和数组元素类型不匹配,编译时可能有警告,运行时会出错。

内容的提问来源于stack exchange,提问作者Mark Louprette Jr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:04:58