public static int findClosestColorIndex(int targetColor) {
        int targetR = (targetColor >> 16) & 0xFF;
        int targetG = (targetColor >> 8) & 0xFF;
        int targetB = targetColor & 0xFF;

        int closestIndex = 0;
        int minDistance = Integer.MAX_VALUE;

        for (int i = 0; i < DYE_COLORS.size(); i++) {
            ColorEntry entry = DYE_COLORS.get(i);
            int entryR = (entry.rgb >> 16) & 0xFF;
            int entryG = (entry.rgb >> 8) & 0xFF;
            int entryB = entry.rgb & 0xFF;

            int dr = targetR - entryR;
            int dg = targetG - entryG;
            int db = targetB - entryB;
            int distance = dr*dr + dg*dg + db*db;

            if (distance < minDistance) {
                minDistance = distance;
                closestIndex = i;
            }
        }
        return closestIndex;
    }

edit this to use oklab internally for better precision.

i already have this suite of methods you can make use of (the linear methods take in individual r,g and b):
 private static double srgbToLinear(double c) {
        return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
    }

make note of how the oklab method swaps the colors here:
 private static double[] okLabToLinearRgb(double L, double a, double b) {
        double l_ = L + 0.3963377774 * a + 0.2158037573 * b;
        double m_ = L - 0.1055613458 * a - 0.0638541728 * b;
        double s_ = L - 0.0894841775 * a - 1.2914855480 * b;

        double l = l_ * l_ * l_;
        double m = m_ * m_ * m_;
        double s = s_ * s_ * s_;

        return new double[]{
                Math.max(0, Math.min(1, -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s)),  // Blue
                Math.max(0, Math.min(1, -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s)),  // Green
                Math.max(0, Math.min(1, +4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s))   // Red
        };
    }

keep that in mind


    private static int linearToSrgb(double linear) {
        double v = linear <= 0.0031308 ?
                linear * 12.92 :
                1.055 * Math.pow(linear, 1 / 2.4) - 0.055;
        return clamp((int) Math.round(v * 255), 0, 255);
    }

    private static double[] linearRgbToOkLab(double r, double g, double b) {
        double l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;
        double m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;
        double s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b;

        double l_ = Math.cbrt(l);
        double m_ = Math.cbrt(m);
        double s_ = Math.cbrt(s);

        return new double[]{
                0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_,
                1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_,
                0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_
        };
    }

    private static double[] okLabToLinearRgb(double L, double a, double b) {
        double l_ = L + 0.3963377774 * a + 0.2158037573 * b;
        double m_ = L - 0.1055613458 * a - 0.0638541728 * b;
        double s_ = L - 0.0894841775 * a - 1.2914855480 * b;

        double l = l_ * l_ * l_;
        double m = m_ * m_ * m_;
        double s = s_ * s_ * s_;

        return new double[]{
                Math.max(0, Math.min(1, -0.0041960863 * l - 0.7034186147 * m + 1.7076147010 * s)),  // Blue
                Math.max(0, Math.min(1, -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s)),  // Green
                Math.max(0, Math.min(1, +4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s))   // Red
        };
    }