繁体   English   中英

如何在Map.Entry中为Map值编写Java 8 Comparator

[英]how to write java 8 Comparator for Map values inside Map.Entry

这是我所拥有的,我想对条目中的值进行降序排序。

Map<String, Outer> outer = Input
                          .entrySet()
                          .stream
                          .collect(toMap(Map.Entry::getKey, entry->{
                           List<Outer> inner = entry
                                    .getValue()
                                    .stream()
                                    .sorted(Comparator.comparingDouble(???))
                              })) ... (more lines of code.)

如何编写一个带有排序的比较器。 如果想做以下里面的排序

if (o1.getSomething() > o2.getSomething())
     return -1;
if (o1.getSomething() < o2.getSomething())
     return 1;
return 0;

获得列表并排序后,它对我有用。

inner.sort((Outer o1, Outer o2) -> {
if (o1.getSomething() > o2.getSomething())
         return -1;
    if (o1.getSomething() < o2.getSomething())
         return 1;
    return 0;
});

但是有没有一种方法可以在条目内部使用stream.sorted(“在这里使用相同的比较器逻辑”)。

Entry是一个ArrayList,带有一堆值。

entry:[{w:1},{w:2},{w:3},{w:4}];

因此,我想对此进行反向排序,如下所示:

entry:[{w:4},{w:3},{w:2},{w:1}];

所以我得到的最终列表是反向排序的。

感到困惑。

如果您只是想获取Map的值并将其放入已排序的List ,则可以执行以下操作:

Map<String, Element> elMap = new HashMap<>();
elMap.put("3", new Element("3"));
elMap.put("2", new Element("2"));
elMap.put("1", new Element("1"));

List<Element> elList = elMap.values()
        .stream()
        .sorted((e1, e2) -> {
            return e1.getSortField().compareTo(e2.getSortField());
        })
        .collect(Collectors.toList());
System.out.println(elList);

在这里,Element是一个简单的POJO,具有一个名为sortField的单个String字段。 sorted()需要一个Comparator 这是一个具有2个参数和一个int返回类型的功能接口。 对于给定的lambda,这没关系。

您还可以让您的元素实现Comparable 然后,您可以执行以下操作:

List<Element> elList = elMap.values()
        .stream()
        .sorted()
        .collect(Collectors.toList());

使用Element实现正确的接口

static class Element implements Comparable<Element> {
    //Constructor, field, getters
    @Override
    public int compareTo(Element o) {
        return this.sortField.compareTo(o.sortField);
    }
}

编辑:

它是Map内的列表,我正在尝试对其进行排序。 并尝试在链本身中对其进行排序。

这可以解释为以下内容:

Map<String, List<Element>> collected = elMap.entrySet()
        .stream()
        .peek(entry -> System.out.println("Performing arbitrary Map operations"))
        .collect(Collectors.toMap(Map.Entry::getKey, entry -> {
            return entry.getValue()
                    .stream()
                    .sorted(Comparator.comparingDouble(Element::getWeight))
                    .collect(Collectors.toList());
        }));

collected.entrySet()
        .forEach(entry -> {
            System.out.println(entry.getKey() + " : " + entry.getValue());
        });

您可以在“ Map.entrySet()”上进行流式传输,并随心所欲地对其进行操作。 根据您的问题将其收集回不同的Map中时,您可以使用上面的示例再次流式传输并收集List

您可以定义Comparator ,然后使用stream.sorted()如下所示并带有内联注释:

//Define comparator Lamda exp for Outer class
Comparator<Outer> outerComparator = (o1, o2) -> {
         if (o1.getValue() > o2.getValue())
                return -1;
          else if (o1.getValue() < o2.getValue())
                return 1;
            else 
              return 0;
   };


Map<String, Outer> output = Input.entrySet(). //get elements
        stream(). //get elements
        sorted( //sort elements by passsing outerComparator
        Map.Entry.<String, Outer>comparingByValue(outerComparator)
        .reversed())//reverse for descending order
        .collect(Collectors.toMap(Map.Entry::getKey, 
        Map.Entry::getValue));//collect to Map object

据我所知,您的问题实际上只是如何创建一个排序列表作为地图中的值,并基于getSomething的返回进行getSomething

entry.getValue().stream()
    .sorted(Comparator.comparing(Outer::getSomething))
    .collect(toList())

将返回根据getSomething排序的列表。 如果该方法返回一个double,则可以使用comparingDouble(Outer::getSomething)避免将值装箱。

如果我猜对了,您想根据给定的比较器对所有值(列表)进行排序。

在这种情况下,您根本不需要创建流。 使用MapreplaceAll方法就足够了:

// Orders Outer elements according to Outer's getSomething method 
// in descendant order (assumes getSomething returns a double value)
Comparator<Outer> yourComparator = 
    Comparator.comparingDouble(Outer::getSomething).reversed();

yourMap.replaceAll((k, v) -> {
        Collections.sort(v, yourComparator);
        return v;
    });

这利用了Collections.sort方法,该方法带有一个列表和一个比较器。

所以这是对我有用的答案。

.sorted(reverseOrder(comparingDouble(Input::getSomething)))

感谢大家,

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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