2017-01-13 5 views
-2

Я хочу построить JSON из двух списков. Мне нужно использовать соответствующие элементы из обоих списков для создания единого объекта JSON.Java 8 Stream с 2 списками

Моя проблема может быть решена с помощью обычного цикла, как это:

List<Class1> items = baseManager.findObjectsByNamedQuery(Class1.class, "Class1.findAll", new Object[]{}); 
for(int i=0 ; i<items.size();i++){ 
     List<Class2> items2 = baseManager.findObjectsByNamedQuery(Class2.class, "Class2.findByCreatedBy" ,new Object[] {items.get(i).getCreatedBy()}); 
     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 
     JsonObjectBuilder jpb = Json.createObjectBuilder() 
       .add("createdBy",items.get(i).getCreatedBy()) 
       .add("phone",items2.get(0).getPhone())    
     groupsBuilder.add(jpb); 
    } 

Можно ли решить его с помощью Java 8 Стрит API?

+2

Пожалуйста, найдите время, чтобы изменить свой вопрос и сделать его более понятным. Я думаю, что четвертая строка в вашем фрагменте предназначена для item2.get (i) ... вместо items.get (i), это правильно? Также есть много опечаток/недостающих слов, из-за которых трудно следовать. «Взгляд на это, но» - но что? То, что вы хотите в целом, возможно, очень просто, и вы должны получить ответ за несколько минут, если вы можете сделать свой вопрос ясным. –

+1

Вы хотите получить неполный код с лямбдами? Поздравляю, у вас уже есть это. – Holger

+0

Я отредактировал ваш вопрос, чтобы звук стал более понятным. Пожалуйста, проверьте, не изменил ли я значение вашего вопроса. Проверьте ответы [здесь] (http://stackoverflow.com/q/30144661/4856258): кажется, что это то, что вы хотите. –

ответ

0

С чистого Java8 потока API:

public void convertItemsToJSon(List<Item> items) { 
    ... 
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 

    Map<Item, List<Class2>> sqlItems = items 
      .stream() 
      .collect(Collectors.toMap(Function.identity(), (item) -> baseManager.findObjectsByNamedQuery(Class2.class, "Class2.findByCratedBy", new Object[]{item.getCreatedBy()}))); 

    sqlItems.entrySet() 
      .stream() 
      .map(sqlItem -> buildJson(sqlItem.getKey(), sqlItem.getValue())) 
      .forEach(groupsBuilder::add); 
    ... 
} 

private JsonObjectBuilder buildJson(Item item, List<Class2> class2Items) { 
    return Json.createObjectBuilder().add("createdBy", item.getCreatedBy()); 
} 

С StreamEx library

public void convertItemsToJSonStreamEx(List<Item> items) { 
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 
    ... 
    StreamEx.of(items) 
      .cross(item -> baseManager.findObjectsByNamedQuery(Class2.class, "Class2.findByCratedBy", new Object[]{item.getCreatedBy()}).stream()) 
      .mapKeys(item -> Json.createObjectBuilder().add("createdBy", item.getCreatedBy())) 
      .mapKeyValue(this::addField) 
      .forEach(groupsBuilder::add); 
    ... 
} 

private JsonObjectBuilder addField(JsonObjectBuilder json, Class2 class2) { 
    // You logic how to convert class2 to field in JSON 
    return json; 
} 
+0

Это не список списков, это 2 списка из 2 SQL -> 1 JSON. List <> ... для (я ...) { 2 Списка по списку форм элемента 1 } как добавить его 2 списка элементов .stream() .map (пункт -> Json.createObjectBuilder() .add ("createdBy", item.getCreatedBy(). add ("telefon", items2.get (0) .get ...()))) .forEach (groupsBuilder :: add); Нравится – Mistu

+0

Скорректированный ответ. Надеюсь, я правильно понял вопрос. –

+1

Я думаю, OP хочет zip. Что-то вроде 'EntryStream.zip (items2, items3) .mapKeyValue ((item2, item3) -> Json.blahblah) .forEach (groupsBuilder :: add)' с StreamEx. –

0

Спасибо за вашу помощь и решения. Наиболее полезным был первый ответ от Влада Бошенина. Код здесь:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 
    items.stream().map(item -> { 
     List<Class2> items2 = baseManager.findObjectsByNamedQuery(Class2.class, "Class2.findByCreatedBy", new Object[]{item.getCreatedBy()}); 
     JsonObjectBuilder jpb = Json.createObjectBuilder() 
       .add("createdBy", item.getCreatedBy()) 
       .add("phone", items2.get(0).getPhone()) 
       return jpb; 
    }).forEach(groupsBuilder::add); 
1

Есть еще некоторые вещи непонятные. Например, почему вы настаиваете на создании этого экземпляра SimpleDateFormat, который вы нигде не используете. Или имеет значение при вызове несколько раз. Если предположить, что это не нужно, следующий код эквивалентен

baseManager.findObjectsByNamedQuery(Class1.class, "Class1.findAll", new Object[]{}) 
    .stream() 
    .map(item -> item.getCreatedBy()) 
    .map(createdBy -> Json.createObjectBuilder() 
     .add("createdBy", createdBy) 
     .add("phone", baseManager.findObjectsByNamedQuery(
      Class2.class, "Class2.findByCreatedBy", new Object[] {createdBy}) 
      .get(0).getPhone()) 
    ) 
    .forEach(jpb -> groupsBuilder.add(jpb)); 

Это до сих пор неясно, мне ли (или почему) findObjectsByNamedQuery не метод переменных аргументов. Было бы вполне естественно, что это метод varargs, не требующий этих явных распределений new Object[] { … }.

+0

или .map (Class1 :: getCreatedBy) и .forEach (groupsBuilder :: add) для тех, кто предпочитает ссылки на методы. –

Смежные вопросы