2

I have an EdmPortfolio type that has id (int), name (String) and tags which is a map as its members.

EdmPortfolio say has an id 1, and name as Portfolio1 and Map could have the following values, analyst, John region, US

I have a List, At the end i want to have a Map which has all the map values combined from all portfolios. Another EdmPortfolio might have the id as 2, name as Portfolio2 and Map with values analyst, Smith region , UK

I want to have a combined Map with Values region 'US','UK' analyst 'John','Smith'

analyst and region are the keys to the map. It has both the maps combined. I have the following code but i am a little lost

List<Map<Tag,String>> portfolioTagsList = new ArrayList<>();
            for (EdmPortfolio edmPortfolio : edmPortfolioList) {
              Map<Tag,String> portfolioTags =  edmPortfolio.getPortfolioTags().entrySet()
                        .stream()

                        .filter(e -> (e.getValue() != ""|| e.getValue() !=null))
                        .collect(Collectors.toMap(
                                Map.Entry::getKey,
                                Map.Entry::getValue
                        ));


                portfolioTagsList.add(portfolioTags);
            }
            Map<Tag,String> finalTags = portfolioTagsList.stream()
                    .flatMap(m -> m.entrySet().stream())
                    .collect(Collectors.groupingBy(Map.Entry::getKey, Collectors.joining(",",Map.Entry::getValue)));

I am getting nonstatic method cannot be referenced from static context. How do i achieve this?

Thanks for your time

Holger
  • 285,553
  • 42
  • 434
  • 765
user3897533
  • 417
  • 1
  • 8
  • 24
  • On which line are you getting that error? Is it even a line from the code in your question? – Robby Cornelissen Dec 06 '17 at 05:51
  • Possible duplicate of [What is the reason behind "non-static method cannot be referenced from a static context"?](https://stackoverflow.com/questions/290884/what-is-the-reason-behind-non-static-method-cannot-be-referenced-from-a-static) – Robby Cornelissen Dec 06 '17 at 05:55

2 Answers2

4

I'd do something like:

Map<Tag,String> finalTags = edmPortfolioList.stream()
.flatMap(edmPortfolio -> edmPortfolio.getPortfolioTags().entrySet().stream())
.filter(e -> (e.getValue() != "" || e.getValue() !=null)) // this seems weird, but just keeping
.collect(Collectors.groupingBy(e -> e.getKey(), 
    Collectors.mapping(ev -> ev.getValue(), 
        Collectors.joining(",")));

BTW: Any reason to break that in two streams?

Bruno Medeiros
  • 2,251
  • 21
  • 34
  • @Holger As the OP didn't provide the exact error message nor where it happens, I just tried come up with a simplified version, with less inferred types, so the same result could be successfully achieved. BTW, your comment about the joining makes sense, I edited my answer accordingly. – Bruno Medeiros Dec 06 '17 at 09:47
  • 1
    The OP did provide the exact error message, though not where it happens, but for the “*nonstatic method cannot be referenced from static context*”, the location wouldn’t be helpful anyway. I’ve seen it so often and always was baffled by what actual problem caused it. Simplifying this to a single operation is indeed a good thing and you already have my upvote, but to the compiler, it adds even more inference work, making it harder to track this dreaded “*nonstatic method cannot be referenced from static context*” error. I really hope for future compiler improvements in this area… – Holger Dec 06 '17 at 09:53
  • Yes, that makes sense, the location is irrelevant for this error. I'm just wondering now if the Eclipse Java Compiler does something different, because I've never seem such failures to be reported under this message. – Bruno Medeiros Dec 06 '17 at 09:57
  • 2
    Yes, ECJ works differently. I’ve seen misleading error messages with ECJ too, but not with such a preference for a single error. Also, they’re used in a different context, e.g. the IDE’s assistants make a difference, e.g. Eclipse is more eager (than Netbeans) in inserting needed `import` statements, which makes is less likely to encounter a lambda related error that is actually a missing import. – Holger Dec 06 '17 at 10:17
  • Thank you. i was trying to understand and simplify thats why i broke it into two streams.. no reason – user3897533 Dec 06 '17 at 17:28
4

Unfortunately, “nonstatic method cannot be referenced from static context” is the error that javac often ends up when type inference fails, especially in the context of method references or lambda expressions. The actual cause could be a wrong generic type parameter, a forgotten import statement, the use of a lambda expression or method reference at an inappropriate place, or even a misplaced or forgotten brace somewhere.

In your case, it’s Collectors.joining(",",Map.Entry::getValue) as that collector has no parameter of a function type that could accept a method reference.
You should use Collectors.mapping(Map.Entry::getValue, Collectors.joining(",")) instead.

Besides that, follow BrunoJCM’s suggestion to use a single stream operation and pay attention to the filter condition. e.getValue() != "" || e.getValue() !=null makes no sense as a reference can never be both, a reference to "" and the null reference, hence, this condition is always fulfilled. You most likely wanted to express that the string must not be null and not an empty string. In this regard, you should not compare strings by reference but use equals. For testing for an empty string, there is the alternative to use isEmpty() instead of equals(""). So the condition should be e.getValue()!=null && !e.getValue().isEmpty(). Mind the order, as we can invoke isEmpty() only after having verified that it is not null.

Holger
  • 285,553
  • 42
  • 434
  • 765