使用Java 8流过滤2个数组组合对象元素

时间:2018-09-01 20:14:30

标签: java arrays java-8 java-stream

我有2个数组对象,第一个是复合对象,另一个是对象的简单数组,根据找到的匹配项进行比较,创建一个新列表。那将是基于条件的过滤列表。我使用Java 1.7版本做到了这一点,但是寻求指导,如果使用java-8可以用更少的代码实现。

这是我的代码,它基于条件过滤器创建一个新列表

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;
}

我试图在流中转换数组,然后使用过滤器,但是以某种方式无法精确比较两个不同的元素,即:

  1. accountOid[i]个数组(简单数组)中的accountOid
  2. accts[j].getAccountOid()数组中的
  3. AccountHoldCompisiteObj(复合 数组)

2 个答案:

答案 0 :(得分:3)

我想您的目标是将内部for-loop转换为外部ObjectId。实际上,您所做的只是将从每个AccountHoldCompositeObject收到的String对象与一组预定义的ObjectId OID(作为要比较的.clone()的模板)进行比较。不需要Set<ObjectId>

在进入Stream之前,我建议先准备数据以便流畅,易于操作和使用。您最后想要的是在lambda内部执行复杂的转换。做:

  1. 定义一组String的转换后的OID(ObjectIdSet<ObjectId>)。
  2. 迭代列表并使用预定义的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 中可用的OID搜索列表。
  3. 将其余的收集到所需的输出。

您在这里:

my_tuples = {
     "tuple1":(1,2,3),
     "tuple2":(3,5,6),
}

答案 1 :(得分:2)

有很多for循环,我添加了如下新代码。我注释了一些行以了解发生了什么。

public static void main(String[] args) {

        final List<AccountHoldCompositeObj> accts = prepare();
        Set<ObjectId> setOfAccountObjectId = IntStream.range(1, 8) //Int stream range between 1-8
                .map(str -> new ObjectId(str)) // Create ObjectId
                .collect(Collectors.toSet()); // Collect into Set

        accts.stream()                                          // Stream for AccountHoldComposite array
                .filter(acct -> setOfAccountObjectId.contains(acct.getAccountOid()))   // Filter elements by existing ids
                .collect(Collectors.toList())
                .forEach(System.out::println);
    }

    private static List<AccountHoldCompositeObj> prepare() {
        int k = 10;
        //creating AccountHoldCompositeObj elements between 0-50
        return Stream.iterate(0, m -> m + 1)
                .limit(50)
                .map(currentId -> {
                    AccountHoldCompositeObj create = new AccountHoldCompositeObj();
                    create.setAccountId(Integer.toString(k));//some more elements
                    create.setAccountOid(new ObjectId(currentId));
                    return create;
                })
                .collect(Collectors.toList());

    }

编辑:我为您的Stream.iterate之间的for loop添加了0 and 50