Рассчитанная оценка случая в выключателе (java) - PullRequest
2 голосов
/ 27 апреля 2020

Я задавал себе этот вопрос некоторое время, это базовый c вопрос, но я никогда не мог сделать это каким-либо другим способом

Цель это исключить else if в коде

У меня действительно есть это:

String contentType = parser.getMimeMessage().getContentType().toLowerCase(); 
//contentType can be for example: "text/a; charset=us-ascii"

String content = parser.getPlainContent(); 

if (contentType.indexOf("text/a") > 0) {
 processTextA(content);

} else if (contentType.indexOf("text/b") > 0) {
 processTextB(content);

} else if (contentType.indexOf("text/c") > 0) {
 processTextC(content);
}

Я хотел бы сделать что-то похожее на это:

String contentType = parser.getMimeMessage().getContentType().toLowerCase();
//contentType can be for example: "text/a; charset=us-ascii"

String content = parser.getPlainContent();

switch (contentType) {
 case (contentType.indexOf("text/a") > 0):
  processTextA(content);
  break;

 case (contentType.indexOf("text/b") > 0):
  processTextB(content);
  break;

 case (contentType.indexOf("text/c") > 0):
  processTextC(content);
  break;
}

Есть ли способ достичь чего-то похожего на это?

В примере я поставил 3 else if, но реальность такова, что у меня есть примерно 20 else if один позади другого

РЕДАКТИРОВАТЬ

contentType может быть text/a; charset=us-ascii, однако также может быть charset=us-ascii; text/a;

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

Я привел это в качестве примера, но вопрос в том, что необходимо вычислить статистику случая

Ответы [ 3 ]

1 голос
/ 27 апреля 2020

Можно создать карту операции textType ->. Например:

 static Map<String, Consumer<String>> operationMap = new HashMap<>();
    static {
        operationMap.put("text/a", this::processTextA);
        operationMap.put("text/b", this::processTextC);
    }

    public static void process(String contentType, String content) {
      operationMap.get(content).accept(content)
    }
1 голос
/ 27 апреля 2020

Цель состоит в том, чтобы исключить else if в коде

В этом нет ничего плохого, если вы будете просты. Но вот вы:

@RequiredArgsConstructor // https://projectlombok.org/api/lombok/RequiredArgsConstructor.html
enum MyContentType {
    NONE(""),
    A("text/a"),
    B("text/a"),
    C("text/a"),
    ;

    static MyContentType from(String contentTypeHeader) {
        final String header = contentTypeHeader.toLowerCase();
        return Arrays.stream(MyContentType.values())
                .skip(1)
                .filter(e -> header.contains(e.headerSubstring))
                .findFirst().orElse(NONE);
    }

    private final String headerSubstring;
}

и затем включите элемент MyContentType.


В примере я поставил 3 еще, если, но реальность такова У меня около 20 else if один за другим

В чем проблема?

  • Если читабельность, то убедитесь, что вы не делаете все, кроме одного простого вызова метода внутри. Или используйте мой подход.
  • Если скорость, то будьте уверены, что обработка обычно занимает много порядков больше времени. Поскольку строка известна заранее, вы можете оптимизировать ее с помощью некоторого интеллектуального алгоритма, но это, скорее всего, пустая трата времени.
1 голос
/ 27 апреля 2020

Для начала я бы использовал:

contentType.contains("text/a")

вместо:

contentType.indexOf("text/a") > 0

Если я правильно вас понял, в вашем * 1008 может быть только один contentType * (выведено это тем, что вы использовали else if вместо if). Вы можете просто разделить contentType на ;, чтобы получить желаемую часть строки. Затем вы можете переключить регистр на строку. Как то так:

String contentType = parser.getMimeMessage().getContentType().toLowerCase();
//contentType can be for example: "text/a; charset=us-ascii"

String content = parser.getPlainContent();

String contentTypeSplitted = contentType.split(";")[0];
switch (contentTypeSplitted) {
 case ("text/a"):
  processTextA(content);
  break;

 case ("text/b"):
  processTextB(content);
  break;

 case ("text/c"):
  processTextC(content);
  break;
}
...