Как реализовать пару ключ-значение с изменчивостью в ключе - PullRequest
0 голосов
/ 07 января 2019

Я пишу код для дублирования данных на основе 2 полей:

  1. Строка символов, мы назовем это UMI
  2. Массив целых чисел

Я создал POJO для хранения этих данных и работы в качестве ключа для TreeMap. Полный набор данных хранится в значении - таким образом, я храню только соответствующие данные в памяти.

Тем не менее, следующим требованием является изменчивость UMI И целых чисел. Например, следующие две части данных будут считаться дубликатами на основе UMI, имеющего изменчивость (несоответствие) 1.

а. "AAA", [200 300]

б. "АБА", [200 300]

Аналогичным образом, следующее будет считаться дубликатами на основе целочисленного массива с учетом допустимого несоответствия 2.

а. «AAA», [201,300]

б. "AAA", [203 300]

Моя текущая попытка состояла в том, чтобы этот POJO реализовал интерфейс Comparable и попытался применить метод compareTo, чтобы учесть изменчивость:

public class UMIPrimoKey implements Comparable<UMIPrimoKey> {

    private final String UMI;
    private final int[] ints;
    private final int umiMisMatch;
    private final int posMisMatch;

    public UMIPrimoKey(String UMI, int[] ints, int umiMisMatch, int posMisMatch) {
        this.UMI = UMI;
        this.ints = ints;
        this.umiMisMatch = umiMisMatch;
        this.posMisMatch = posMisMatch;
    }

    @Override
    public int compareTo(UMIPrimoKey o) {
        if (!Arrays.equals(ints, o.ints)) {
            if (ints.length == o.ints.length) {
                for (int i = 0; i < ints.length; i++) {
                    if (Math.abs(ints[i] - o.ints[i]) > posMisMatch) {
                        return -1;
                    }
                }
            } else {
                return -1;
            }
        }

        if (XsamStringUtils.numberOfDifferences(UMI, o.UMI) <= umiMisMatch) {
            return 0;
        }

        return 1;
    }
}

XsamStringUtils.numberOfDifferences - это простой статический метод подсчета количества различий между двумя UMI.

Я возвращаю -1, если любые два целых числа из массива имеют разницу, превышающую допустимые несоответствия (posMisMatch). 0 возвращается, если разрешены целые числа, а количество несовпадений в UMI меньше разрешенного количества, указанного в umiMisMatch.

В противном случае возвращается 1, поскольку UMI не совпадают.

Затем я использовал это в TreeMap, который учитывает метод compareTo.

Это работает в моих модульных тестах, с добавлением небольшого числа UMIPrimoKey с, но я получаю некоторые странные результаты при запуске завершенной программы. Вероятно, это связано с правилами для метода, изложенными здесь: https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html, но мне трудно адаптировать код для учета правил.

Любое направление приветствуется, спасибо за чтение!

1 Ответ

0 голосов
/ 07 января 2019

Согласно документам для сравнения:

Разработчик должен обеспечить sgn (x.compareTo (y)) == -sgn (y.compareTo (x)) для всех x и y. (Это означает, что x.compareTo (y) должно вызвать исключение, если y.compareTo (x) генерирует исключение.)

Разработчик также должен обеспечить транзитивность отношения: (x.compareTo (y)> 0 && y.compareTo (z)> 0) подразумевает x.compareTo (z)> 0.

Наконец, разработчик должен убедиться, что x.compareTo (y) == 0 подразумевает, что sgn (x.compareTo (z)) == sgn (y.compareTo (z)) для всех z.

Я думаю, что это не относится к вашему коду, и это может вызвать проблемы с функцией get, не находящей вашу запись

...