Как обрабатывать исключение NumberFormatException с помощью Java StreamAPI

Есть ли способ отфильтровать все значения, превышающие максимальное значение, которое может быть сохранено в Long с помощью Stream API?

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

Например: 123456789, 10987654321. Если между этими двумя идентификаторами поставить "разделитель", все работает. Но если вы забудете "разделитель", мой код попытается преобразовать 12345678910987654321 в длинное, и я думаю, проблема в этом.

Это вызывает NumberFormatException после попытки поиска. Есть ли способ отфильтровать эти числа, которые нельзя преобразовать в Long, потому что они слишком большие?

String hyphen = "-";

String[] customerIds = bulkCustomerIdProperty.getValue()
              .replaceAll("[^0-9]", hyphen)
              .split(hyphen);
...
customerFilter.setCustomerIds(Arrays.asList(customerIds).stream()
              .filter(n -> !n.isEmpty()) 
              .map(n -> Long.valueOf(n)) // convert to Long
              .collect(Collectors.toSet()));
Основы программирования на Java
Основы программирования на Java
Java - это высокоуровневый объектно-ориентированный язык программирования, основанный на классах.
Концепции JavaScript, которые вы должны знать как JS программист!
Концепции JavaScript, которые вы должны знать как JS программист!
JavaScript (Js) - это язык программирования, объединяющий HTML и CSS с одной из основных технологий Всемирной паутины. Более 97% веб-сайтов используют...
4
0
68
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Может быть, вы могли бы добавить еще один фильтр, например

.filter((n) -> { return new BigInteger(n).compareTo(new BigInteger(String.valueOf(Long.MAX_VALUE))) <= 0;})

Вы также можете использовать try/catch, чтобы выдать ошибку, когда это произойдет, и уведомить свой интерфейс.

Это не сработает. Если для этого сравнения он уже был преобразован в тип long, проблема уже возникла. Вы можете изменить фильтр на .filter(n -> !n.isEmpty() && (new BigInteger(n).compareTo(MAXLONG)) <= 0), определив BigInteger MAXLONG

g00se 10.04.2022 18:16

@g00se g00se Вы правы, я переработал свое решение на основе вашего предложения.

Csisanyi 10.04.2022 19:14
Ответ принят как подходящий

Вы можете либо выделить синтаксический анализ в отдельный метод и обернуть его try/catch, либо использовать BigInteger для исключения значений, выходящих за пределы диапазона long.

Пример с BigInteger:

Set<Long> result =  Stream.of("", "12345", "9999999999999999999999999999")
        .filter(n -> !n.isEmpty())
        .map(BigInteger::new)
        .filter(n -> n.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) <= 0 &&
                     n.compareTo(BigInteger.valueOf(Long.MIN_VALUE)) >= 0)
        .map(BigInteger::longValueExact) // convert to Long
        .peek(System.out::println) // printing the output
        .collect(Collectors.toSet());

Пример с обработкой NumberFormatException в отдельном методе:

Set<Long> result =  Stream.of("", "12345", "9999999999999999999999999999")
        .filter(n -> !n.isEmpty())
        .map(n -> safeParse(n))
        .filter(OptionalLong::isPresent)
        .map(OptionalLong::getAsLong) // extracting long primitive and boxing it into Long
        .peek(System.out::println) // printing the output
        .collect(Collectors.toSet());

public static OptionalLong safeParse(String candidate) {
    try {
        return OptionalLong.of(Long.parseLong(candidate));
    } catch (NumberFormatException e) {
        return OptionalLong.empty();
    }
}

Выход (из peek())

12345

Другие вопросы по теме