使用流处理异常

我有一个Map<String,List<String>>并希望它变成Map<String,List<Long>>因为String列表中的每个代表一个Long:


Map<String,List<String>> input = ...;

Map<String,List<Long>> output= 

input.entrySet()

       .stream()

       .collect(toMap(Entry::getKey, e -> e.getValue().stream()

                                                      .map(Long::valueOf)

                                                      .collect(toList()))

               );

我的主要问题是每个都String可能无法正确代表Long; 可能有一些问题。Long::valueOf可能会引发异常。如果是这种情况,我想返回 null 或空Map<String,List<Long>>


因为我想迭代这张output地图。但我不能接受任何错误的转换;连一个也没有。知道如何在 String -> Long 转换不正确的情况下返回空输出吗?


白板的微信
浏览 121回答 4
4回答

慕娘9325324

我个人喜欢提供Optional有关数字解析的输入:public static Optional<Long> parseLong(String input) {    try {        return Optional.of(Long.parseLong(input));    } catch (NumberFormatException ex) {        return Optional.empty();    }}然后,使用您自己的代码(并忽略错误的输入):Map<String,List<String>> input = ...;Map<String,List<Long>> output= input.entrySet()       .stream()       .collect(toMap(Entry::getKey, e -> e.getValue().stream()                                                      .map(MyClass::parseLong)                                                      .filter(Optional::isPresent)                                                      .map(Optional::get)                                                      .collect(toList()))               );此外,考虑一个辅助方法来使其更加简洁:public static List<Long> convertList(List<String> input) {    return input.stream()        .map(MyClass::parseLong).filter(Optional::isPresent).map(Optional::get)        .collect(Collectors.toList());}public static List<Long> convertEntry(Map.Entry<String, List<String>> entry) {    return MyClass.convertList(entry.getValue());}然后您可以在流收集器中过滤结果:Map<String, List<Long>> converted = input.entrySet().stream()    .collect(Collectors.toMap(Entry::getKey, MyClass::convertEntry));您还可以将空Optional对象保留在列表中,然后通过将新对象List<Optional<Long>>(而不是List<Long>)中的索引与原始对象进行比较List<String>,您可以找到导致任何错误输入的字符串。您也可以简单地将这些失败记录在MyClass#parseLong但是,如果您的愿望是根本不对任何不良输入进行操作,那么我将采取的路线是围绕您试图捕获的整个流。

守着星空守着你

显式地处理异常怎么样catch:private Map<String, List<Long>> transformInput(Map<String, List<String>> input) {&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; return input.entrySet()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(Long::valueOf)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toList())));&nbsp; &nbsp; } catch (NumberFormatException nfe) {&nbsp; &nbsp; &nbsp; &nbsp; // log the cause&nbsp; &nbsp; &nbsp; &nbsp; return Collections.emptyMap();&nbsp; &nbsp; }}

鸿蒙传说

您可以创建一个StringBuilderfor 键(但有例外)并检查是否ele为数字,如下所示,&nbsp;public static Map<String, List<Long>> transformInput(Map<String, List<String>> input) {&nbsp; &nbsp; StringBuilder sb = new StringBuilder();&nbsp; &nbsp; try {&nbsp; &nbsp; return input.entrySet()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(ele->{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!StringUtils.isNumeric(ele)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sb.append(e.getKey()); //add exception key&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new NumberFormatException();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Long.valueOf(ele);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toList())));} catch (NumberFormatException nfe) {&nbsp; &nbsp; System.out.println("Exception key "+sb);&nbsp; &nbsp; return Collections.emptyMap();}}希望能帮助到你。

慕斯王

也许您可以编写一个辅助方法,该方法可以检查字符串中的数字并从流中过滤掉它们以及空值,然后最终收集到 Map 中。// StringUtils.javapublic static boolean isNumeric(String string) {&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; Long.parseLong(string);&nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; } catch(NumberFormatException e) {&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; }}这会照顾一切。并在您的信息流中使用它。Map<String, List<Long>> newMap = map.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> mapToLongValues(entry.getValue())));public List<Long> mapToLongValues(List<String> strs) {&nbsp; &nbsp; return strs.stream()&nbsp; &nbsp; &nbsp; &nbsp; .filter(Objects::nonNull)&nbsp; &nbsp; &nbsp; &nbsp; .filter(StringUtils::isNumeric)&nbsp; &nbsp; &nbsp; &nbsp; .map(Long::valueOf)&nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toList());}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java