简体   繁体   English

Java8 流收集器.ToMap 方法引用失败

[英]Java8 streams collectors.ToMap Method reference failing

Can someone tell me what is the issue in following example code.有人可以告诉我以下示例代码中的问题是什么。 For sake of example, We can assume all columns are available in resultSet and everything is a String.例如,我们可以假设 resultSet 中的所有列都可用,并且所有内容都是字符串。

Last line in below code is failing.下面代码中的最后一行失败。

ResultSet rs = JdbcTemplate.query(......)

List<String> columnName= <some predefined fixed values> ;


Map<String,String> columnAndValueMap 
                = columnName
                      .stream()
                      .collect(Collectors.toMap(
                                   Function.identity(),
                                   rs::getString)); //Cannot resolve method 'getString'

Collectors.toMap expects a Function<String, String> as its second argument (the value mapper function). Collectors.toMap需要一个Function<String, String>作为它的第二个参数(值映射器函数)。

Function<String, String> is a functional interface that has this single abstract method: Function<String, String>是一个具有这个单一抽象方法的函数式接口:

String apply(String arg);

However, the ResultSet.getString method has the following signature:但是, ResultSet.getString方法具有以下签名:

String getString(String columnLabel) throws SQLException;

As SQLException is a checked exception, it makes the ResultSet.getString method incompatible with the Function.apply method, hence you're getting that error.由于SQLException是已检查的异常,它使ResultSet.getString方法与Function.apply方法不兼容,因此您会收到该错误。


As shown by @vphilipnyc in their answer , you can use a for loop with a try/catch block to handle your scenario.正如@vphilipnyc 在他们的回答中所示,您可以使用带有try/catch块的for循环来处理您的场景。 Or, if you want to stick to a more functional approach, you might declare your own functional interface, that adapts a SQLException throwing function to a common java.util.function.Function (via inheritance):或者,如果您想坚持使用更函数式的方法,您可以声明自己的函数式接口,将SQLException抛出函数调整为通用java.util.function.Function (通过继承):

@FunctionalInterface
public interface SQLFunction<T, R> extends Function<T, R> {

    R applySQL(T t) throws SQLException;

    @Override
    default R apply(T t) {
        try {
            return applySQL(t);
        } catch (SQLException e) {
            throw new RuntimeException(e); // or your own unchecked exception
        }
    }

    static <T, R> Function<T, R> adapt(SQLFunction<T, R> f) {
        return f;
    }
}

Then, you could use it this way:然后,你可以这样使用它:

Map<String, String> columnAndValueMap = columnName.stream()
    .collect(Collectors.toMap(
        Function.identity(),
        SQLFunction.adapt(rs::getString)));

As @fps mentioned, the rs.getString() method throws a SQLException as described in its signature.正如@fps 所提到的, rs.getString()方法会按照其签名中的描述抛出 SQLException。

Assuming you are seeking to create a map with column names as keys and result set strings as values, you can do:假设您正在寻求创建一个以列名作为键和结果集字符串作为值的映射,您可以执行以下操作:

List<String> columnNames = List.of("columnA", "columnB");

Map<String, Object> map = columnNames.stream().collect(
        Collectors.toMap(Function.identity(), s -> {
            try {
                return Optional.ofNullable(rs.getString(s));
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            return s;
        }));

This is a bit messy since you need to catch the SQLException during the stream operations.这有点混乱,因为您需要在流操作期间捕获SQLException Further, an encouraged practice is to use Optional since the getString() method can return a null.此外,鼓励的做法是使用Optional因为getString()方法可以返回 null。 (Understood that you are assuming that there will be no nulls. Your IDE may highlight the lack of Optional as a warning.) (理解您假设不会有空值。您的 IDE 可能会突出显示缺少Optional作为警告。)

You may instead be better off using a simple for loop and surround it with a try/catch:相反,您最好使用简单的 for 循环并用 try/catch 包围它:

Map<String, String> map = new HashMap<>(columnNames.size());
for (String columnName : columnNames) {
    try {
        map.put(columnName, rs.getString(columnName));
    } catch (SQLException throwables) {
        throwables.printStackTrace(); 
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM