Фильтрация 2 элементов составного объекта массива с использованием потока Java 8 - PullRequest
0 голосов
/ 01 сентября 2018

У меня есть 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;
}

Я пытался преобразовать массив в поток, а затем использовал фильтр, но почему-то не смог сравнить ровно 2 разных элемента, то есть:

  1. accountOid[i] из accountOid массив (простой массив)
  2. accts[j].getAccountOid() из AccountHoldCompisiteObj массив (составной массив)

Ответы [ 2 ]

0 голосов
/ 02 сентября 2018

Там много цикла 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.

0 голосов
/ 01 сентября 2018

Полагаю, ваша цель - преобразовать внутреннее for-loop во внешнее. Практически все, что вы делаете, - это сравнение ObjectId объекта, полученного от каждого из AccountHoldCompositeObject, с группой предопределенных String OID в качестве шаблона для ObjectId для сравнения. .clone() не требуется.

Перед входом в Stream я рекомендую сначала подготовить данные для свободного и удобного манипулирования и использования. Последнее, что вы хотите - выполнить сложное преобразование внутри лямбды. Есть:

  1. Определите набор Set<ObjectId> преобразованных OID (от String до ObjectId).
  2. Перебор списка и поиск по OID, доступному в предопределенном Set<ObjectId>.
  3. Соберите оставшиеся до желаемого выхода.

Вот, пожалуйста,

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
...