Filtering 2 array composite object elements using java 8 stream

Rakesh :

I have 2 array objects, the first one is composite and another one is a simple array of object, based upon some comparison if match found, create a new list. That would be a filtered list based upon conditions. I did that using java 1.7 version, however looking for guidance if this can be achievable with less code using java-8.

Here is my code which creates a new list based upon a conditional filter

public static void main(String[] args) throws CloneNotSupportedException {
    String[] accountOid = {"1","2","3","4","5","6","7","8"};
    AccountHoldCompositeObj[] accts = prepare();
    ArrayList<AccountHoldCompositeObj> list = new ArrayList<AccountHoldCompositeObj>(); 
    for (int i = 0; i < accountOid.length; i++) {
        for (int j = 0; j < accts.length; j++) {
            ObjectId oid =  new ObjectId(accountOid[i]);
            if (oid.equals(accts[j].getAccountOid())) {
                AccountHoldCompositeObj anAccount = (AccountHoldCompositeObj) accts[j].clone();                 
                list.add(anAccount);
                break;
            }
        }
    } 

    list.stream().forEach(s->System.out.println(s));
}

private static AccountHoldCompositeObj[] prepare() {
    AccountHoldCompositeObj[] valArr = new AccountHoldCompositeObj[5];
    int k =10;
    for (int i=0;i<50;i++){         
        AccountHoldCompositeObj create = new AccountHoldCompositeObj(); 
        create.setAccountId(Integer.toString(k));//some more elements
        create.setAccountOid(new ObjectId(i)); 
        valArr[i] = create;
        k++;
    }
    return valArr;
}

I tried to convert array in stream and then used filter, but somehow not able to compare exactly 2 different elements, that is :

  1. accountOid[i] of accountOid array (simple array)
  2. accts[j].getAccountOid() of AccountHoldCompisiteObj array (composite array)
Nikolas :

I suppose your goal is to transform the inner for-loop with the outer one. Practically, all you do is a comparison of the ObjectId object received from each of AccountHoldCompositeObject with a group of predefined String OIDs as a template for the ObjectId to be compared. The .clone() is not needed.

Before entering Stream I recommend prepare data first for the fluent and easy manipulation and usage. The last you want is to perform the complicated transformation inside a lambda. Do:

  1. Define a set Set<ObjectId> of the transformed OIDs (String to ObjectId).
  2. Iterate the list and search ones with OID available in the predefined Set<ObjectId>.
  3. Collect the remaining to a desired output.

Here you go:

Set<ObjectId> idSet = Arrays.stream(accountOid)             // Stream over String[]
                            .map(str -> new ObjectId(str))  // Create ObjectId from each
                            .collect(Collectors.toSet());   // Collect to Set<ObjectId>

List<AccountHoldCompositeObj> list = Arrays
    .stream(accts)                                          // Stream over AccountHoldCompositeObj[]
    .filter(acct -> idSet.contains(acct.getAccountOid()))   // Filter elements by IDs
    .collect(Collectors.toList());                          // Collect to List

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=78182&siteId=1