简体   繁体   中英

Is this the right use of java.util.stream?

Update

Ok, I think I know how to work with streams now. The code in the old post is a mess and I'm not proud of it. So, thank you for you help for directing me in the right direction. I wrote a supplier class , which provides me with items and used static filters and mapper functions:

final TradeSupplier tradeSupplier = new TradeSupplier();
Stream.generate(tradeSupplier).map(TradeSupplier::getPrice)
        .map(TradeSupplier::getTradePartner)
        .map(TradeSupplier::getTradeInfo)
        .filter(TradeSupplier::validateInfo)
        .map(TradeSupplier::getPartnerAssetId)
        .filter(TradeSupplier::validatePartnerAssetId).forEach(t -> {
            if (trade.sendTrade(t)) {
                tradeSupplier.finishedItem();
                TradeCache.save(t);
            }
        });

With this design, I don't need flatMap , because it's just an one by one mapping. Additional information is filed into the item, which is just in the stream I hope, this code is better than the code below... What do you think? I'm appreciative for any help to improve my understanding of streams :)


Old post

I'm looking for help for the "new" stream api of java 8: first I get a list of items, for every item I collect a list of strings and after that, i want to combine the string with their corresponding item:

input:

  • item1
  • item2

wanted output:

  • item1; string1
  • item1; string2
  • item2; string1
  • item2; string2
  • item2; string3

Is the following code the right way to use this api?

Code (with stream api)

// input is a list of items
analyst.getInRange(wantMinValue, wantMaxValue)
        .stream()
        .filter(i -> !haveItem.getName().contains(i.getName())
                || (!haveItem.getModel().contains(i.getModel()) && haveItem
                        .getQuality() > i.getQuality()))
// get extra information and add it to a list (key: item; value: string) 
        .collect(Collectors.toMap(s -> s, s -> lounge.getItemId(s)))
        .entrySet()
        .stream()
// delete all null and empty strings 
        .filter(e -> e.getValue() != null && !e.getValue().isEmpty())
// for every entry in list, create an list and add to result
        .forEach(
                e -> {
                    lounge.getListOfValue(e.getValue(), 1)
                            .stream()
                            .filter(s -> s != null && !s.isEmpty())
                            .map(s -> lounge.getStringFromOldString(s))
                            .filter(s -> s != null && !s.isEmpty())
                            .collect(
                                    Collectors
                                            .toCollection(HashSet::new))
// add list to resulting list
                            .forEach(
                                    s -> {
                                        result.add(new TradeLink(s,
                                                haveItem, e.getKey()));
                                    });

                });

First thing: .filter(s -> s != null && !s.isEmpty())

Don't include these things unless these are actually things that can happen. Are empty strings or null strings actually going to come up in your application? (If so, that probably reflects a design flaw in the first place. It may be better to let your application crash, because nulls generally shouldn't be in your program in ways like this.)

Second: don't do the mutable thing you're doing here:

      .forEach(
            e -> {
                lounge.getListOfValue(e.getValue(), 1)
                        .stream()
                        .filter(s -> s != null && !s.isEmpty())
                        .map(s -> lounge.getStringFromOldString(s))
                        .filter(s -> s != null && !s.isEmpty())
                        .collect(
                                Collectors
                                        .toCollection(HashSet::new))
                        // add list to resulting list
                        .forEach(
                                s -> {
                                    result.add(new TradeLink(s,
                                            haveItem, e.getKey()));
                                });

            });

Instead, do something like:

  .flatMap(e ->
                lounge.getListOfValue(e.getValue(), 1)
                        .stream()
                        .map(lounge::getStringFromOldString)
                        .distinct()
                        .map(s -> new TradeLink(s, haveItem, e.getKey()))
  .collect(toList())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM