1

I have a JoinRowSet (jrs) and TreeMap (finalTM). I have a for-loop cycle on the keys of the TreeMap and, for each key, I want to get the records from the JoinRowSet that have this column equal to the value of the TreeMap key, using Java 8 lambda expressions. The lambda expression on the for-loop returns an ArrayList. What I need is to add the values of these ArrayLists to a new CachedRowSet (or JoinRowSet). I have tried other return types on the lambda expression but I have even more issues.

My JoinRowSet has to be converted to a Collection to be used with lambda expressions and each record on the collection has to have the type Row because this is to be used in different apps so it can have no app-specific classes.

Any input on this would be appreciated. Thank you.

This is my code:

List dataList = new ArrayList();

Collection<Row> filteredDataArr = (Collection<Row>) jrs.toCollection();

for (Map.Entry<String,Integer> entry : finalTM.entrySet()) {

    String key = entry.getKey();

    dataList = filteredDataArr.stream() 
            .filter(u -> {
                            try {
                                return ((u.getColumnObject(thisColIdxToGroupBy).toString()).equals(key));
                            } catch (Exception e) {
                                e.printStackTrace();
                                return false;
                            }
                        }
                    )
            .collect(Collectors.toList())
            ;
    System.out.println("#recs: " + dataList.size());
}

Updated: I found a way of doing this looping through the ArrayList and using the insertRow method from CachedRowSet. I'm not sure if this is the most efficient way of doing this though.

CachedRowSet finalCRS = new CachedRowSetImpl();
finalCRS.setMetaData((RowSetMetaData) jrs.toCachedRowSet().getMetaData());
if (dataList != null && dataList.size() > 0) {

    for (Object rec : dataList) {
        finalCRS.moveToInsertRow();

        for (int j = 1; j <= finalCRS.getMetaData().getColumnCount(); j++) {

            String dataType = finalCRS.getMetaData().getColumnTypeName(j);

            if (dataType.equals("NUMBER")) {
                finalCRS.updateBigDecimal(j, (BigDecimal) ((Row)rec).getColumnObject(j));

            } else if (dataType.equals("VARCHAR2")) {
                finalCRS.updateString(j, (String) ((Row)rec).getColumnObject(j));

            } else if (dataType.equals("DATE")) {
                finalCRS.updateTimestamp(j, (Timestamp) ((Row)rec).getColumnObject(j));
            }
        }
        finalCRS.insertRow();
        finalCRS.moveToCurrentRow();

    }
}
  • Your entire operation does it wrong when it comes to efficiency. You are iterating over a `TreeMap` which has a fairly fast lookup (`O(log(n))`) and linearly searching in a `RowSet`. You should do it the other way, iterating over the `RowSet` *one time* and check whether the key is inside the `TreeMap` to benefit from the `TreeMap`’s faster than linear lookup. – Holger Oct 10 '14 at 17:53
  • `dataList = filteredDataArr.stream().filter(finalTM::containsKey()).collect(toList())` – user2418306 Oct 12 '14 at 00:46
  • If you take out filtering into sql (where it should be) then you can cache your result simply by `crs.populate(rs)` – user2418306 Oct 12 '14 at 01:11
  • Thank you for your help. Holger, I tried that and it worked ok as well. I still have a lot of testing to do but I will stay with your reply. user2418306, I wish I could put the filtering into the SQL but I can't. This is for a feature that I don't agree with but I have to do it. – user3682705 Oct 16 '14 at 11:31

0 Answers0