【问题标题】:Make a generic function in Java用Java制作一个泛型函数
【发布时间】:2021-11-04 13:42:52
【问题描述】:

我有两种方法可以从数据库中获取数据。它们仅在请求和返回类型上有所不同。是否有可能以某种方式将它们组合起来以使代码不会重复?

public ObservableList<Car> getAllCars() {
    ObservableList<Car> list = FXCollections.observableArrayList();
    Connection connection = MyConnection.connection;
    String query = "SELECT * FROM cars";
    try {
        Statement statement = connection.createStatement();
        ResultSet rs = statement.executeQuery(query);
        while (rs.next()) {
            Car car = new Car(rs.getInt("ID"), rs.getInt("STYLE_ID"),
                    rs.getString("MAKE"), rs.getString("MODEL"),
                    rs.getInt("YEAR"), rs.getInt("PRICE"));
            list.add(car);
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return list;
}

public ObservableList<Style> getAllStyles() {
    ObservableList<Style> list = FXCollections.observableArrayList();
    Connection connection = MyConnection.connection;
    String query = "SELECT * FROM styles";
    try {
        Statement statement = connection.createStatement();
        ResultSet rs = statement.executeQuery(query);
        while (rs.next()) {
            Style style = new Style(rs.getInt("ID"), rs.getString("NAME"));
            list.add(style);
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return list;
}

【问题讨论】:

    标签: java function generics


    【解决方案1】:

    您可以先编写一个函数式接口,表示将ResultSet 转换为某种类型T 的函数:

    @FunctionalInterface
    interface ResultConverter<T> {
        T convert(ResultSet resultSet) throws SQLException;
    }
    

    然后你可以写一个通用函数,接受ResultConverter&lt;T&gt;

    public <T> ObservableList<T> getAll(ResultConverter<T> converter, String query) {
        ObservableList<T> list = FXCollections.observableArrayList();
        Connection connection = MyConnection.connection;
        try {
            Statement statement = connection.createStatement();
            ResultSet rs = statement.executeQuery(query);
            while (rs.next()) {
                T t = converter.convert(rs);
                list.add(t);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return list;
    }
    

    那么你可以将不重复的部分留在getAllStylesgetAllCars中:

    // getAllCars:
    return getAll(rs -> new Car(rs.getInt("ID"), rs.getInt("STYLE_ID"),
                    rs.getString("MAKE"), rs.getString("MODEL"),
                    rs.getInt("YEAR"), rs.getInt("PRICE")),
                  "SELECT * FROM cars");
    
    // getAllStyles:
    return getAll(rs -> new Style(rs.getInt("ID"), rs.getString("NAME")),
                  "SELECT * FROM styles");
    

    【讨论】:

    • 差不多:每种类型都需要不同的 SQL 查询。
    • @MauricePerry 好收获!谢谢。
    • @AndyTurner 我假设ResultSetjava.sql.ResultSet,所以getIntgetString 等抛出SQLException。如果我使用Function,您将不得不在 lambda 中捕获异常,这在 IMO 中看起来很可怕。当然,如果ResultSet 是别的东西,并且getInt 不会抛出已检查的异常,那么我肯定会使用Function&lt;ResultSet, T&gt;
    • @Sweeper 很公平,没有注意到投掷。
    • 最好使用@FunctionalInteface 标记功能接口。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    相关资源
    最近更新 更多