JAVA возвращает самое длинное значение, если строка содержит какие-либо элементы из списка - PullRequest
4 голосов
/ 16 февраля 2020

У меня есть следующий массив типов кода:

["sample_code","code","formal_code"]

и следующие идентификаторы:

String id="123456789_sample_code_xyz";
String id2="91343486_code_zxy";

Я хочу извлечь тип кода из идентификаторов

это мой фрагмент кода:

    String codeTypes[] = {"sample_code","code","formal_code"};
    String id= "123456789_sample_code_xyz";
    String codeType = Arrays.stream(codeTypes).parallel().filter(id::contains).findAny().get();
    System.out.println(codeType);

он не работает с 1-м идентификатором, потому что он возвращает «код» вместо «sample_code», я хочу получить самый длинный тип кода.

for the 1st id the code type should be "sample_code"
for the 2nd id the code type should be "code"

Ответы [ 4 ]

4 голосов
/ 16 февраля 2020

Сначала проверьте самые длинные типы кода. Это означает следующие изменения в вашем коде:

  1. Сортировка типов кода по убыванию длины.
  2. Не используйте параллельный поток. У параллельного потока нет заказа. Последовательный поток гарантирует, что типы кода проверяются по порядку.
  3. Используйте findFirst(), а не findAny(), чтобы убедиться, что вы получите первое совпадение.

Таким образом, это становится:

    String codeTypes[] = { "sample_code", "code", "formal_code" };
    Arrays.sort(codeTypes, Comparator.comparing(String::length).reversed());

    String id = "123456789_sample_code_xyz";
    Optional<String> codeType = Arrays.stream(codeTypes).filter(id::contains).findFirst();
    codeType.ifPresent(System.out::println);

Теперь вывод:

sample_code

1 голос
/ 16 февраля 2020

Вы можете сделать это следующим образом:

public class Main {
    public static void main(String[] args) {
        String[] ids = { "123456789_sample_code_xyz", "91343486_code_zxy" };
        String[] codeTypes = { "sample_code", "code", "formal_code" };
        String max;
        for (String id : ids) {
            max = "";
            for (String codeType : codeTypes) {
                if (id.contains(codeType)) {
                    if (max.length() < codeType.length()) {
                        max = codeType;
                    }
                }
            }
            System.out.println(id + " : " + max);
        }
    }
}

Вывод:

123456789_sample_code_xyz : sample_code
91343486_code_zxy : code
0 голосов
/ 16 февраля 2020

Ну, потоковый API не подходит для каждой проблемы. Я думаю, что вы можете использовать не потоковую версию для решения вашей проблемы.

Я только что перебрал массив codeTypes и для каждого codeType заменил idx пустой строкой, затем вычислил ее длину и нашел минимальную длину между строкой idX и заменил. теперь, если minSize длина с replace длина строки одинакова, то он является кандидатом на конечный результат. minSize != id.length() - это время, когда не существует codeType.

private static String findCodeType(String id, String[] codeTypes) {
    int minSize = id.length();
    String codeType = "NotFound";
    for (String code : codeTypes) {
        String replace = id.replaceAll(code, "");
        minSize = Integer.min(minSize, replace.length());
        if (minSize == replace.length() && minSize != id.length())
            codeType = code;
    }
    return codeType;
}
0 голосов
/ 16 февраля 2020

Поскольку вы запускаете strem параллельно, вы не можете предсказать, какой из потоков сначала найдет соответствующий шаблон. В вашем случае (также в моем, когда я попробовал ваш фрагмент кода) второй поток, который искал "код", был быстрее, и весь поток завершается, потому что вы просто хотите "findAny ()".

Remove " параллельно ", и ваш код работает, как вы ожидаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...