Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从JAVA+;堆栈溢出错误_Java_Arrays - Fatal编程技术网

从JAVA+;堆栈溢出错误

从JAVA+;堆栈溢出错误,java,arrays,Java,Arrays,我需要找到一种快速有效的方法,在数组项中创建唯一的对(如果有两个以上) 我的第一个问题是,我提出的这段代码有时抛出java.lang.StackOverflowerError,为什么?我知道助手中的递归调用会让它变得更深入,但是如何修复它呢 我的第二个问题是如何使代码更高效。我不需要使用数组-它可以是其他集合类型 这就是我想到的: import java.util.HashMap; import java.util.concurrent.ThreadLocalRandom; /** * Ge

我需要找到一种快速有效的方法,在数组项中创建唯一的对(如果有两个以上)

我的第一个问题是,我提出的这段代码有时抛出java.lang.StackOverflowerError,为什么?我知道助手中的递归调用会让它变得更深入,但是如何修复它呢

我的第二个问题是如何使代码更高效。我不需要使用数组-它可以是其他集合类型

这就是我想到的:

import java.util.HashMap;
import java.util.concurrent.ThreadLocalRandom;

/**
 * Generates unique pairs from items in array. Each item cannot occur more than
 * once as key nor value.
 *
 * @author lkallas
 */
public class UniquePairs {

    private static final String[] NAMES
            = new String[]{"Aaron", "Barney", "Charlie", "Desiré", "Edward"};

    private static final HashMap<String, String> PAIRS = new HashMap<>();

    public static void main(String[] args) {

        // Check if there is more than one item in array.
        if (NAMES.length > 1) {
            // Find pairs
            for (String name : NAMES) {
                if (!PAIRS.containsKey(name)) {
                    PAIRS.put(name, helper(name));
                }
            }
            // Show results.
            PAIRS.entrySet().stream().forEach((pair) -> {
                System.out.println(pair.getKey() + " - " + pair.getValue());
            });
        } else {
            System.out.println(NAMES[0]);

        }
    }

    /**
     * Helper for finding partner.
     *
     * @param key Name that need partner.
     * @return Unique partner.
     */
    private static String helper(String key) {

        // Get random partner from array.
        String partner = NAMES[getRandomInt(0, NAMES.length - 1)];

        // Cannot pair up a name with itself. Also partner cannot occur more than once.
        if (key.equals(partner) || PAIRS.containsValue(partner)) {
            partner = helper(key);
        }
        return partner;
    }

    /**
     * Random integer in the given range.
     *
     * @param min Minimum value of the random integer.
     * @param max Maximum value of the random integer.
     * @return Random integer in given range.
     */
    private static int getRandomInt(int min, int max) {

        return ThreadLocalRandom.current().nextInt(min, max + 1);
    }

}
而不是

return new Random().nextInt((max - min) + 1) + min;
编辑2:

为这种操作创建了特殊类。如有必要,请随意使用

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;

/**
 *
 * @author lkallas
 */
public class MatchMaker {

    private final Map<Object, Object> PAIRS;
    private List<? extends Object> items;

    public MatchMaker() {
        this.PAIRS = new HashMap<>();
    }

    /**
     * Pairs items uniquely and randomly so that keys nor values are repeated.
     * For proper pairing of Objects it is recommended to provide your own
     * implementation of <code>equals()</code> method. Also bear in mind that
     * you should also override <code>hashCode()</code> if there's any chance of
     * your objects being used in a hash table.
     *
     * @param input List with objects that are paired with each other.
     * @return Map with generated pairs.
     * @throws IllegalArgumentException When input List is empty or contains
     * only one item.
     */
    public Map<?, ?> getPairs(List<? extends Object> input)
            throws IllegalArgumentException {

        if (input.size() > 1) {

            items = input;

            for (int i = 0; i < input.size() - 1; i++) {
                Object k = input.get(i);
                PAIRS.put(k, getPartner(k));
            }

            Object k = items.get(items.size() - 1);
            if (PAIRS.containsValue(k)) {
                PAIRS.put(k, getPartner(k));
            } else {
                Object k1 = items.get(getRandomInt(0, items.size() - 1));
                PAIRS.put(k, PAIRS.get(k1));
                PAIRS.put(k1, k);
            }
        } else {
            throw new IllegalArgumentException("Can't pair one or less items.");
        }
        return PAIRS;
    }

    /**
     * Helper for finding a random partner.
     *
     * @param key Object that needs partner.
     * @return Unique partner that is not used by other keys.
     */
    private Object getPartner(Object key) {

        // Get random partner from array.
        Object partner = items.get(getRandomInt(0, items.size() - 1));

        // Cannot pair up a key with itself. Also partner cannot occur more than once.
        if (key.equals(partner) || PAIRS.containsValue(partner)) {
            partner = getPartner(key);
        }
        return partner;
    }

    /**
     * Random integer in the given range.
     *
     * @param min Minimum value of the random integer.
     * @param max Maximum value of the random integer.
     * @return Random integer in given range.
     */
    private static int getRandomInt(int min, int max) {

        return ThreadLocalRandom.current().nextInt(min, max + 1);
    }
}
改变这个

for (String name : NAMES) {
    if (!PAIRS.containsKey(name)) {
        PAIRS.put(name, helper(name));
    }
}

for(int i=0;i

您的版本发生了什么,请参见。基本上,在最后一步中,您的选项已经用完,因此
helper
会反复调用自身,直到出现
StackOverflowerError
为止。

TLDR,但是
getRandomInt
是一个错误:您不应该每次都创建一个新的
Random
对象。我昨天解释过这一点。你们俩是同一个班还是什么的@保尔·伯丁顿不,我们不是!这甚至不是家庭作业或smth。这只是我想创造的一段代码,让我的生活更轻松。好吧,我的答案解释了会发生什么。如果在最后一步没有选项,
helper
将继续调用自身,直到发生
stackoverflower错误。如果选项数为零,则需要进行交换。由于java 7,您可以简单地使用
ThreadLocalRandom.current().nextInt(min,max)
[max+1,如果您的意思是包含的话](出于某种原因,min/max方法是TLR独有的)没有问题。我很高兴能帮上忙。
for (String name : NAMES) {
    if (!PAIRS.containsKey(name)) {
        PAIRS.put(name, helper(name));
    }
}
for (int i = 0; i < NAMES.length - 1; i++) {
    String name = NAMES[i];
    PAIRS.put(name, helper(name));
}
String name = NAMES[NAMES.length - 1];
if (PAIRS.containsValue(name)) {
    PAIRS.put(name, helper(name));
} else {
    String otherKey = NAMES[ThreadLocalRandom.current().nextInt(0, NAMES.length - 1)];
    PAIRS.put(name, PAIRS.get(otherKey));
    PAIRS.put(otherKey, name);
}