7
\$\begingroup\$

I have a module that builds swing tables based on an Object[][], then I have another module that queries an SQLite database and returns a ResultSet.

I have written a method that converts the ResultSet to an ArrayList<Object[]> first, then further into an Object[][]. The reason I do it this way is because you cannot get the row count from the ResultSet without iterating over it.

I'm wondering if there is a more efficient way to build my Object[][] from the ResultSet without having to iterate over the data twice.

Here is the method that performs the conversion:

public Object[][] executeQuery(String query) throws SQLException{
    ResultSet rs = getResultSet(query);
    ResultSetMetaData rsMetaData = rs.getMetaData();
    int columnCount = rsMetaData.getColumnCount();
    ArrayList<Object[]> result = new ArrayList<Object[]>();
    Object[] header = new Object[columnCount];
    for (int i=1; i <= columnCount; ++i){
        Object label = rsMetaData.getColumnLabel(i);
        header[i-1] = label;
    }
    while (rs.next()){
        Object[] str = new Object[columnCount];
        for (int i=1; i <= columnCount; ++i){
            Object obj = rs.getObject(i);
            str[i-1] = obj;
        }
        result.add(str);
    }
    int resultLength = result.size();
    Object[][] finalResult = new Object[resultLength][columnCount];
    finalResult[0] = header;
    for(int i=1;i<resultLength;++i){
        Object[] row = result.get(i);
        finalResult[i] = row;
    }
    return finalResult;
}
\$\endgroup\$
10
\$\begingroup\$

Well, you could just call the toArray method of your list to transform the list into an array. Or even better, you could make the table model use a List<Object[]> rather than an Object[][], which would avoid the unnecessary conversion.

\$\endgroup\$
2
  • \$\begingroup\$ +1 toArray does the same thing as the posted code, but better. You can actually get the row count by doing another query first, but it's definitely not worth it. \$\endgroup\$
    – Viruzzo
    Jan 11 '12 at 16:10
  • \$\begingroup\$ Yeah, I looked at using another query to get the row count, but I came to the same conclusion. \$\endgroup\$ Jan 11 '12 at 16:16
3
\$\begingroup\$

I agree with @JB Nizet, some other notes about the current implementation:

  1. Use the List interface as reference type instead of the implementation type. I mean change

    ArrayList<Object[]> result = ...
    

    to

    List<Object[]> result = ...
    

    Type List vs type ArrayList in Java

  2. I'd change the indexing in the for loops:

    for (int i = 0; i < columnCount; ++i) {
        final Object label = metaData.getColumnLabel(i + 1);
        header[i] = label;
    }
    

    I think for (i = 0; i < max; i++) style looks more familiar for most programmers.

  3. I'd extract out a getHeaders method:

    private Object[] getHeaders(final ResultSetMetaData metaData) throws SQLException {
        final int columnCount = metaData.getColumnCount();
        final Object[] header = new Object[columnCount];
        for (int i = 0; i < columnCount; ++i) {
            final Object label = metaData.getColumnLabel(i + 1);
            header[i] = label;
        }
        return header;
    }
    
\$\endgroup\$
2
\$\begingroup\$

I think there is a bug where we lose the first record of data

int resultLength = result.size();

should be int resultLength = result.size()+1;

Object[] row = result.get(i);

should be Object[] row = result.get(i-1);

Here's the fix:

int resultLength = result.size()+1;
Object[][] finalResult = new Object[resultLength][columnCount];
finalResult[0] = header;
for(int i=1;i<resultLength;++i){
    Object[] row = result.get(i-1);
    finalResult[i] = row;
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ ResultSet is 1 based. \$\endgroup\$
    – Kiril
    Jun 5 '15 at 14:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.