0

I have a list of objects that are returned from an external API and each object looks like this:

public class Item {
    public String id;
    public int processingType;
    public String appliedToItemId;
    public Float chargeAmount;
}

Objects with a processingType value of 1 need to be "applied" to another object which will have a processingType of 0. The objects are linked with appliedToItemId and id. Once the objects are grouped then I would like to be able to merge them into one object.

This is something I could do with LINQ in C# but wanted to learn if it would be possible with streams introduced in Java 8.

C# would be something like this:

// seperate out items into two lists (processingTypeOneItems, processingTypeTwoItems)
...

// join items
var joinedItems =
    from i in processingTypeTwoItems
    join j in processingTypeOneItems on i.id equals j.appliedToItemId into gj
    from item in gj.DefaultIfEmpty()
    select new { id = i.id, chargeAmount = i.chargeAmount, discountAmount = item?.chargeAmount ?? 0 }; 

As can be seen, the items are matched on i.id == j.appliedToItemId and then the objects are merged into an object of anonymous type. I am really confused since most examples I have seen simply group by one attribute.

Is it possible in Java to group in this custom manner where the value of one attribute is compared to the value of another attribute?

z-siddiqi
  • 37
  • 1
  • 8
  • 2
    Grouping and joining are two entirely different operations. – Holger Feb 17 '22 at 10:27
  • 1
    @Holger, it is how this LINQ query built- GroupJoin(...).SelectMany(...). Actually OP is trying to do in Java `LEFT JOIN` for objects. – Svyatoslav Danyliv Feb 17 '22 at 11:00
  • 1
    `Once the objects are grouped then I would like to be able to merge them into one object` - Your class `Item` doesn't have such a functionality. What does this method look like? – Alexander Ivanchenko Feb 17 '22 at 11:20
  • 3
    @SvyatoslavDanyliv Your comment reads like an answer to a question I never asked. – Holger Feb 17 '22 at 11:51
  • 1
    @Holger, just explaining why OP called it Grouping. NET has function `GroupJoin` which groups items by key and as result you have pair Outer + Inner items. – Svyatoslav Danyliv Feb 17 '22 at 12:01
  • Thanks everyone for pointing me in the right direction, appreciate the comments. I realise now my question was a bit misguided as I didn't really understand how to get my point across. I will edit the question to better reflect my problem and will post a rudimentary solution I have since figured out. – z-siddiqi Feb 18 '22 at 15:24

1 Answers1

1
        var joinedItems = processingTypeTwoItems.stream()
                .map(item -> new Item() {{
                        id = item.id;
                        processingType = item.processingType;
                        appliedToItemId = item.appliedToItemId;
                        chargeAmount = processingTypeOneItem.stream().filter(i -> i.appliedToItemId.equals(item.id)).findFirst().orElse(new Item() {{chargeAmount = 0.0f;}}).chargeAmount;
                    }}).collect(Collectors.toList());
Falah H. Abbas
  • 512
  • 5
  • 11