2017-08-10 36 views
4

我想写一个函数,需要一个地图,并返回一个条目。如果具有最大整数值的条目是唯一的,它应该返回该条目。但是,如果有重复的条目具有相同的最大值,则应该返回一个带有“MULTIPLE”键且值为0的新条目。容易获得忽略重复的最大值:Java流:获取最大,如果没有重复

public static Entry<String,Integer> getMax(Map<String,Integer> map1) { 
    return map1.entrySet().stream() 
          .max((a,b) -> a.getValue().compareTo(b.getValue())) 
          .get(); 
} 

但为了让我按照我刚才所说的去做,我只能找到一个解决方案,我必须创建一个初始流来做布尔检查,如果有多个最大值,然后做另一个流,如果没有得到值。我想找到一个解决方案,我可以只用一个流来完成这两项任务。

这是我的小测试的情况:

@Test 
    public void test1() { 
     Map<String,Integer> map1 = new HashMap<>(); 
     map1.put("A", 100); 
     map1.put("B", 100); 
     map1.put("C", 100); 
     map1.put("D", 105); 

     Assert.assertEquals("D", getMax(map1).getKey()); 

     Map<String,Integer> map2 = new HashMap<>(); 
     map2.put("A", 100); 
     map2.put("B", 105); 
     map2.put("C", 100); 
     map2.put("D", 105); 

     Assert.assertEquals("MULTIPLE", getMax(map2).getKey()); 
+0

究竟是两个流的问题?为什么你需要把它归结为一个? –

+0

没有问题。我只想知道这是否可能,如果是的话,如何去做。 – wlaem

回答

1

这是一个简单的缩减情况,并且您不需要任何外部库。

Map.Entry<String, Integer> max(Map<String, Integer> map) { 
    return map.entrySet().stream() 
      .reduce((e1, e2) -> { 
       if (e1.getValue() == e2.getValue()) { 
        return new SimpleImmutableEntry<>("MULTIPLE", 0); 
       } else { 
        return Collections.max(asList(e1, e2), comparingInt(Map.Entry::getValue)); 
       } 
      }) 
      .orElse(new SimpleImmutableEntry<>("NOT_FOUND", 0)); 
} 
+1

好主意,你不需要:Collections.max(asList(e1,e2),comparatorInt(Map.Entry :: getValue)); e1.getValue()> e2.getValue()? e1:e2足够好 –

+0

好。现在,我正在填写更多字符以供评论。 –

+0

这很有趣...其实我认为答案是不正确的 –

1

下面是StreamEx

public Entry<String, Integer> getMax(Map<String, Integer> map) { 
    return StreamEx.of(map.entrySet()).collect(collectingAndThen(MoreCollectors.maxAll(Map.Entry.comparingByValue()), 
      l -> l.size() == 1 ? l.get(0) : new AbstractMap.SimpleImmutableEntry<>("MULTIPLE", 0))); 
} 

另一种解决方案是与潜在的性能更好迭代地图两次解:

public Entry<String, Integer> getMax(Map<String, Integer> map) { 
    int max = map.entrySet().stream().mapToInt(e -> e.getValue()).max().getAsInt(); 

    return StreamEx.of(map.entrySet()).filter(e -> e.getValue().intValue() == max).limit(2) 
      .toListAndThen(l -> l.size() == 1 ? l.get(0) : new AbstractMap.SimpleImmutableEntry<>("MULTIPLE", 0)); 
} 
+1

你好。我们注意到几乎所有近期的答案都在推广第三方图书馆StreamEx。总的来说,它看起来像你的答案是完整的,并与问题相关,所以感谢你试图遵循我们的指导方针。但是,如果您以某种方式隶属于StreamEx,则需要在答案中明确地[透露您的联系](https://stackoverflow.com/help/promotion)。否则,社区往往认为这是垃圾邮件或“astroturfing”,这是不受欢迎的。 –

+0

我不隶属于StreamEx。唯一的原因就是StreamEx是一个伟大的库,它可以/应该用来解决很多Java 8流API相关的问题 –

+0

Cool。那么不用担心。我们刚收到一些用户的标志,他们怀疑几乎所有的答案都在推广这个图书馆。也许在你遇到问题时回答其他类型的问题? :-)正如我所说的,你已经通过展示*图书馆如何解决问题而做得很好,所以请保持良好的工作。 –