4

I want to find out if the HashMap has all its values empty or not. What is the best way to do it other than having to check the value in every entry in the map?

HashMap<Long, Optional<Long>> aMap = new HashMap<>();

aMap.put(new Long(55), Optional.empty());
aMap.put(new Long(66), Optional.empty());
aMap.put(new Long(77), Optional.empty());
aMap.put(new Long(99), Optional.empty());
Mehraj Malik
  • 14,872
  • 15
  • 58
  • 85
Ganga
  • 597
  • 2
  • 9
  • 23
  • 1
    There is *no* way of doing it other than checking every entry in the map, but there are various ways of doing that. @SotiriosDelimanolis Solution in that link will not work for `Optional`. – user207421 Mar 12 '18 at 01:16
  • @EJP Why wouldn't it? An `allMatch` with `Optional::isPresent`? – Sotirios Delimanolis Mar 12 '18 at 01:17
  • @SotiriosDelimanolis I didn't see that solution in the link, and the question clearly specifies 'other than checking every value'. – user207421 Mar 12 '18 at 01:18
  • @EJP Am I misreading [this](https://stackoverflow.com/a/35282505/438154)? – Sotirios Delimanolis Mar 12 '18 at 01:19
  • Or more duplicates: https://stackoverflow.com/questions/24304129/how-to-check-if-all-elements-of-java-collection-match-some-condition – Sotirios Delimanolis Mar 12 '18 at 01:19
  • 4
    This seems like a bad use of `Optional`. A map should just not have values instead of having placeholder "empty" ones. – chrylis -cautiouslyoptimistic- Mar 12 '18 at 01:40
  • 1
    @chrylis I don't think that's necessary true, if you've ever had a hashmap with a null value, this is probably a better way than checking null. – Jose Da Silva Gomes Mar 12 '18 at 01:43
  • 1
    @chrylis Thanks for this comment. I was originally using 2 lists of equal sizes and was suggested to put them in a map. But i know the fact that the values are going to be always with all entries or all empty. So a map with Optional does not really fit my actual use case, would not have realized this until reading your comment, although it was good learning how to check all empty values:) – Ganga Mar 12 '18 at 01:50
  • As a side note, you should never use `new Long(…)`. The preferred way is `Long.valueOf(…)` or just use a plain long value like `55L` and let the compiler use autoboxing, which will call `Long.valueOf(55L)` under the hood. – Holger Mar 12 '18 at 09:01

2 Answers2

10

Use java 8 stream's API.

Using allMatch

boolean allEmpty = aMap.values()
    .stream()
    .allMatch(opt -> !opt.isPresent());

Or using noneMatch

boolean allEmpty = aMap.values()
    .stream()
    .noneMatch(Optional::isPresent);

An important thing to note from the documentation, is that both methods are 'short-circuiting terminal operations'

This is a short-circuiting terminal operation.

This means that the method doesn't need to evaluate the entire stream, when it founds the first match in noneMatch or the first mismatch in allMatch it returns immediatly.

Jose Da Silva Gomes
  • 3,814
  • 3
  • 24
  • 34
-6

There is no way of doing it other than checking the value in every entry in the map (of course stopping when you find a non-null), but there are various ways of doing that, and no doubt many answers showing how will be posted.

user207421
  • 305,947
  • 44
  • 307
  • 483