【问题标题】:Generic choose of method / infering methods in javajava中方法/推断方法的通用选择
【发布时间】:2017-11-17 00:37:14
【问题描述】:

我完全没有使用泛型的经验,但我设置了一些代码。 我的目标是实现searchData(ResultSet rs),以便它选择与data 对应的正确方法,data 是给定的类/数据库字段名称。

例子:

对于data = "medium" 我想打电话给searchMedium(rs)

对于data = "客户" 我想打电话给searchCustomer(rs)

对于data = "贷款" 我想打电话给searchLoan(rs)

我不想用 if 或 switch case 来实现它,因为这对于许多方法来说会变得很大。 我希望你能理解我的意图,并且有可能实现它。 这是我的代码:

public class test3 {
public static void main(String[] args) {
    test3 t = new test3();
    ArrayList<?> list = t.search("medium");
    for (int i = 0; i < list.size(); i++) {
        System.out.println(list.get(i));
    }
}

public <T> ArrayList<T> search(String data) {
    ArrayList<T> resultList = new ArrayList<T>();
    Connection c;
    Statement stmt;
    String sql = "Error occurred before executing SQL statement";
    try {
        Class.forName("org.sqlite.JDBC");
        c = DriverManager.getConnection("jdbc:sqlite:library.sqlite");
        c.setAutoCommit(false);
        stmt = c.createStatement();
        sql = "SELECT * FROM " + data + ";";
        ResultSet rs = stmt.executeQuery(sql);

        resultList = searchData(rs, data);
        rs.close();
        stmt.close();
        c.close();
    } catch (Exception e) {
        System.err.println(e.getClass().getName() + ": " + e.getMessage() + "\n" + sql + "\nSQL query for " + data
                + " failed");
    }
    return resultList;
}

private <T> ArrayList<T> searchData(ResultSet rs, String data) {
    ArrayList list = null;
    // TODO ???
    return list;
}

private ArrayList<Loan> searchLoan(ResultSet rs) throws SQLException {
    ArrayList<Loan> resultList = new ArrayList<Loan>();
    Loan match;
    while (rs.next()) {
        int loanNumber = rs.getInt("NUMBER");
        String mediumId = rs.getString("MEDIUMCODE");
        int customerNumber = rs.getInt("CUSTOMERNUMBER");
        String loanDate = rs.getString("LOANDATE");
        String targetReturndate = rs.getString("TARGETRETURNDATE");
        String returnDate = rs.getString("RETURNDATE");
        int extensions = rs.getInt("EXTENSIONS");
        match = new Loan(loanNumber, mediumId, customerNumber, targetReturndate, loanDate, returnDate, extensions);
        resultList.add(match);
    }
    return resultList;
}

private ArrayList<Medium> searchMedium(ResultSet rs) throws SQLException {
    ArrayList<Medium> resultList = new ArrayList<Medium>();
    Medium match;
    while (rs.next()) {
        String number = String.valueOf(rs.getInt("NUMBER"));
        String id = rs.getString("ID");
        String isbn = rs.getString("ISBN");
        String title = rs.getString("TITLE");
        String authors = rs.getString("AUTHORS");
        String type = rs.getString("TYPE");
        String category = rs.getString("CATEGORY");
        String publishingYear = String.valueOf(rs.getInt("PUBLISHINGYEAR"));
        String publishingMonth = rs.getString("PUBLISHINGMONTH");
        String timestamp = rs.getString("TIMESTAMP");
        String loanerNumber = String.valueOf(rs.getInt("LOANERNUMBER"));
        match = new Medium(number, id, isbn, title, type, authors, category, publishingYear, publishingMonth,
                timestamp, loanerNumber);
        resultList.add(match);
    }
    return resultList;
}

private ArrayList<Customer> searchCustomer(ResultSet rs) throws SQLException {
    ArrayList<Customer> resultList = new ArrayList<Customer>();
    Customer match;
    while (rs.next()) {
        String number = String.valueOf(rs.getInt("NUMBER"));
        String id = rs.getString("ID");
        String lastname = rs.getString("LASTNAME");
        String firstname = rs.getString("FIRSTNAME");
        String birthdate = rs.getString("BIRTHDATE");
        String zipcode = String.valueOf(rs.getInt("ZIPCODE"));
        String domicile = rs.getString("DOMICILE");
        String street = rs.getString("STREET");
        String housenumber = String.valueOf(rs.getInt("HOUSENUMBER"));
        String notification = rs.getString("NOTIFICATION");
        String notificationTimestamp = rs.getString("NOTIFICATIONTIMESTAMP");
        match = new Customer(number, id, lastname, firstname, birthdate, zipcode, domicile, street, housenumber,
                notification, notificationTimestamp);
        resultList.add(match);
    }
    return resultList;
}

}

可能我的方法非常糟糕,所以我很乐意得到任何帮助/建议。

非常感谢

【问题讨论】:

  • switch 有什么问题?您期望有多少个值?
  • 数据库中的每一列都会有一个特定的方法,因此很容易增长到一百多个案例。像haskell这样的真正的lambda表达式可以解决这个问题,但是java中有什么对应的吗?我只知道带有来自 java8 的功能接口的 lambda,但那是更多的语法糖......
  • case 添加到switch 与创建新方法相比非常简单。
  • 你可以使用反射来按名称调用方法,但我不建议这样做。
  • 选择不是在 switch case 和创建新方法之间。我必须使用 switch case 来调用我需要创建的新方法。问题是是否有必要编写那个巨大的 switch case,因为它很快就会变得难以维护。

标签: java generics methods inference


【解决方案1】:

据我了解,这里不能使用泛型来动态调用方法。为此,您必须使用方法重载。如果你愿意放弃Generics,那么可以使用下面的方式。

private RestultSet getResultSet(String tblName){
    Connection c;
    Statement stmt;
    String sql = "Error occurred before executing SQL statement";
    try {
        Class.forName("org.sqlite.JDBC");
        c = DriverManager.getConnection("jdbc:sqlite:library.sqlite");
        c.setAutoCommit(false);
        stmt = c.createStatement();
        sql = "SELECT * FROM " + tblName+ ";";
        ResultSet rs = stmt.executeQuery(sql);

        return rs;
    } catch (Exception e) {
        System.err.println(e.getClass().getName() + ": " + e.getMessage() + "\n" + sql + "\nSQL query for " + data
            + " failed");
    }
}

public ArrayList<Customer> search(Customer c) {
    ArrayList<Customer> resultList = new ArrayList<>();
    ResultSet rs = getRestultSet(c.getSimpleName());

    Customer match;
    while (rs.next()) {
        String number = String.valueOf(rs.getInt("NUMBER"));
        String id = rs.getString("ID");
        String lastname = rs.getString("LASTNAME");
        String firstname = rs.getString("FIRSTNAME");
        String birthdate = rs.getString("BIRTHDATE");
        String zipcode = String.valueOf(rs.getInt("ZIPCODE"));
        String domicile = rs.getString("DOMICILE");
        String street = rs.getString("STREET");
        String housenumber = String.valueOf(rs.getInt("HOUSENUMBER"));
        String notification = rs.getString("NOTIFICATION");
        String notificationTimestamp = rs.getString("NOTIFICATIONTIMESTAMP");
        match = new Customer(number, id, lastname, firstname, birthdate,     zipcode, domicile, street, housenumber,
            notification, notificationTimestamp);
        resultList.add(match);
    }

    rs.close();
    return resultList;
}

public ArrayList<Medium> search(Medium m) {
    ArrayList<Medium> resultList = new ArrayList<>();
    ResultSet rs = getRestultSet(m.getSimpleName());

    Medium match;
    while (rs.next()) {
        String number = String.valueOf(rs.getInt("NUMBER"));
        String id = rs.getString("ID");
        String isbn = rs.getString("ISBN");
        String title = rs.getString("TITLE");
        String authors = rs.getString("AUTHORS");
        String type = rs.getString("TYPE");
        String category = rs.getString("CATEGORY");
        String publishingYear = String.valueOf(rs.getInt("PUBLISHINGYEAR"));
        String publishingMonth = rs.getString("PUBLISHINGMONTH");
        String timestamp = rs.getString("TIMESTAMP");
        String loanerNumber = String.valueOf(rs.getInt("LOANERNUMBER"));
        match = new Medium(number, id, isbn, title, type, authors, category, publishingYear, publishingMonth,
            timestamp, loanerNumber);
        resultList.add(match);
    }

    rs.close();
    return resultList;
}

同样你也可以放上贷款的搜索方法。

主要方法如下

public static void main(String[] args) {
    test3 t = new test3();
    ArrayList<?> list = t.search(new Medium());
    for (int i = 0; i < list.size(); i++) {
        System.out.println(list.get(i));
    }
}

希望这会奏效...谢谢...

【讨论】:

  • 这不起作用,因为问题仍然存在,它只是重组。此外,每次将列对象插入 t.search(...) 时,我都必须找出参数,因为所有这些对象都是使用构造函数中作为参数给出的数据构建的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 1970-01-01
  • 2011-06-27
  • 1970-01-01
  • 2020-06-11
相关资源
最近更新 更多