参考方法Java 8

时间:2015-03-28 21:12:56

标签: java java-8

我想要洗牌清单。我想这样做的方法是在java 8列表中使用sort方法。 我想为每个数字分配0到1之间的随机数,并根据该数字对列表进行排序。 这就是我拥有和运作的方式:

List<Integer> list = Arrays.asList(1,2,3,4,5);
list.sort(comparing(x->new Random().nextFloat()));

它有效。但是当我想使用这样的参考方法时:

list.sort(comparing(Random::nextFloat));

我得到编译时错误,我不明白为什么。毕竟我的比较器为每个元素生成随机数,然后按此随机数排序。 有什么想法吗?

提前感谢你

1 个答案:

答案 0 :(得分:5)

comparing()方法要求您传递一个Function Integer并返回一个排序键,即Float(或float在这种情况下。

班级nextFloat()中的Random方法不会使用Integer(或int)参数,因此对Random::nextFloat的方法引用不起作用 - 该方法没有预期的签名。

你可以制作一个辅助方法:

public class Example {
    private final Random rnd = new Random();

    private float nextFloat(int dummy) {
        return rnd.nextFloat();
    }

    public void shuffle() {
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        list.sort(comparing(this::nextFloat));
    }
}

但是还有一个更大的问题。此解决方案没有按照您的想法行事:

  

我想为每个数字指定0到1之间的随机数,并根据该数字对列表进行排序。

不是为列表中的每个数字指定一个随机数,而是根据该数字进行排序,而是每次调用比较方法时返回一个不同的随机数。您正在使用的排序算法可能会为同一个整数多次调用比较方法。在这种情况下,您每次都会返回一个不同的随机数。

这可能会导致非常奇怪的问题,具体取决于您使用的排序算法。它甚至可能永远不会终止。

正确实施此操作比您想象的要复杂得多。如果这是针对实际应用而不仅仅是练习,请使用Collections.shuffle()而不是自己实现。

这是一个工作版本:

import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.Random;
import java.util.stream.Collectors;

import static java.util.Comparator.comparing;

public final class ShuffleExample {

    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);

        // Create a list of Entry objects, which are pairs of a random float
        // and a value from the list
        Random rnd = new Random();
        List<Entry<Float, Integer>> entries = new ArrayList<>();
        for (Integer value : list) {
            entries.add(new SimpleEntry<>(rnd.nextFloat(), value));
        }

        // Sort the list of Entry objects by the floats
        entries.sort(comparing(Entry::getKey));

        // Get the int values out of the sorted list
        List<Integer> shuffled = entries.stream()
                .map(Entry::getValue)
                .collect(Collectors.toList());

        System.out.println(shuffled);
    }
}