【问题标题】:Update contents of Arraylist per iteration每次迭代更新 Arraylist 的内容
【发布时间】:2017-11-20 05:42:23
【问题描述】:

我正在尝试找到一种方法来更新 ArrayList 的内容,如果根据条件迭代地删除一个元素。我所拥有的是一种算法,它使用用户选择的方法(通过 switch case)以特定方式解决问题。但是,如果经过一定次数的迭代后没有发现改进,它会随机选择不同的可用方法(案例)。

目标: 如果选择了一种方法,则它不应再次可用。

代码:

        public Solution solve() throws IOException, EclipseException {

        // Account for all the available switch cases
        ArrayList<Integer> selection = new ArrayList<Integer>();
        for(int y = 1; y < 12; y++) {
            selection.add(new Integer(1*y));
        }

        ArrayList<Integer> listToKeep = new ArrayList<Integer>();

        for (int i = 0; i < iterations; i++) {

        // Iterative process with a counter for each iteration that provides 
        // no improvement 

            if (counter == 6) {
                for (Integer num : selection) {
                    if (num != method){
                        listToKeep.add(num);
                        }
                }
                selection.clear();
                selection.addAll(listToKeep);
                System.out.println("Sent for selection " + selection);

                Random rand = new Random(); 
                method = selection.get(rand.nextInt(selection.size()));
                System.out.println("New randomly selected method is: " + method);

                solve(method);
            }
        }   
        return bestSolution;
    }

期望的结果:

All cases: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] 
Initital method chosen: 1

Sent for selection [2, 3, 4, 5, 6, 7, 8, 9, 10, 11] 
New randomly selected method is: 8

Sent for selection [2, 3, 4, 5, 6, 7, 9, 10, 11]
New randomly selected method is: 9

etc.

问题: for 循环一直引用包含所有数字的原始 ArrayList 选择(而不是基于 listToKeep 更新的),并且只删除最后选择的案例。

问题: 如何确保每次迭代都正确更新选择 ArrayList?

非常感谢任何反馈或替代方法!

解决方案编辑 18-06

        if (!alreadyExecuted){
            selection = IntStream.range(1, 12).boxed().collect(Collectors.toList());
            Collections.shuffle(selection);
        }
        alreadyExecuted = true;

        int newMethod = selection.get(selection.size() - 1);
        selection.remove(selection.size() - 1);

【问题讨论】:

    标签: java arraylist iteration


    【解决方案1】:

    而不是从列表中删除随机元素, 打乱列表会更简单,更有效, 并且总是取最后一个元素。

    List<Integer> selection = IntStream.range(1, 13).boxed().collect(Collectors.toList());
    Collections.shuffle(selection);
    

    此列表的最后一个元素将是随机的。 删除最后一个元素很便宜。 (如果是 ArrayList 在您的示例中, 删除中间的元素需要复制它之后的元素。)

    【讨论】:

    • 感谢 Janos 提供了非常聪明的选择。如果我理解正确:1)我的新方法等于洗牌列表的最后一个元素。 2) 此后最后一个元素被删除。
    • @ArjenPeters 没错,然后要么删除最后一个元素,要么使用索引来跟踪要选择的下一个元素。
    • @乔纳斯·罗杰!我想我必须玩一点。使用方法 = selection.get(selection.size() - 1); selection.remove(selection.size() - 1);列表长度保持不变。
    • @ArjenPeters 我看不出列表在selection.remove(selection.size() - 1) 之后如何保持相同的长度。我怀疑你忽略了一些东西。
    • @Jonas 是的,我想我找到了问题所在。同时,我已接受您的回答,以感谢您的努力。
    【解决方案2】:

    您可以在并发修改的情况下使用Iterator。类似的东西

    List<Integer> selection = new ArrayList<>();
    
    for (Iterator<Integer> iterator = selection.iterator(); iterator.hasNext();) {
        Integer val = iterator.next();
        if (check_for_condition) {
            // Remove the current element from the iterator and the list.
            iterator.remove();
        }
    }
    

    【讨论】:

    • 谢谢!我之前有一个非常相似的迭代器,如果条件为真,它可以删除元素,但它没有像我想要的结果中描述的那样在多次迭代中更新选择的整体内容。但我会仔细检查并回复你。
    猜你喜欢
    • 2023-04-03
    • 2022-01-10
    • 1970-01-01
    • 2018-03-01
    • 2017-10-29
    • 2019-11-29
    • 2015-09-06
    • 2016-04-09
    • 1970-01-01
    相关资源
    最近更新 更多