Java - 实现循环循环列表,并计算元素的访问次数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22869350/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 18:32:57  来源:igfitidea点击:

Java - Implementing a round-robin circular List, and counting element's access count?

javaiteratorload-balancingcircular-listround-robin

提问by Wuaner

Scenario:

设想:



For a list that have 3 elements [A, B, C]:

对于具有 3 个元素 [A, B, C] 的列表:

You can circular access it as many times as you want. And there is a additional counting function records access count of each element.

您可以根据需要多次循环访问它。并且有一个额外的计数功能记录每个元素的访问计数。

For example, if accessing it 7 times, should return:

例如,如果访问它 7 次,应该返回:

    [A, B, C, A, B, C, A]

And have access count of each element as following:

并具有每个元素的访问计数如下:

    +–––––––––––+–––––––––––––––+
    |  Element  |  Access count |
    +–––––––––––––––––––––––––––+
    |     A     |       3       |
    +–––––––––––––––––––––––––––+
    |     B     |       2       |
    +–––––––––––––––––––––––––––+
    |     C     |       2       |
    +–––––––––––+–––––––––––––––+

Any response would be greatly appreciated.

任何回应将不胜感激。

Regards.

问候。



Updated

更新



Add another additional function that allow caller to specify a elements list that should be filtered. Still use 7 times accessing as a example, filtering [C]:

添加另一个附加函数,允许调用者指定应过滤的元素列表。仍然以7次访问为例,过滤[C]:

    [A, B, A, B, A, B, A]

    +–––––––––––+–––––––––––––––+
    |  Element  |  Access count |
    +–––––––––––––––––––––––––––+
    |     A     |       4       |
    +–––––––––––––––––––––––––––+
    |     B     |       3       |
    +–––––––––––––––––––––––––––+
    |     C     |       0       |
    +–––––––––––+–––––––––––––––+

And, the subsequent calling on getNextOne() should always fetch the one that access count is low (Simulate a load-balanced accessing count implementation.). So, if second caller attempt to accessing it 10 times, should return:

并且,对 getNextOne() 的后续调用应始终获取访问计数较低的那个(模拟负载平衡访问计数实现。)。因此,如果第二个调用者尝试访问它 10 次,则应返回:

    [C, C, C, B, C, A, B, C, A, B, C, A]

    +–––––––––––+–––––––––––––––+
    |  Element  |  Access count |
    +–––––––––––––––––––––––––––+
    |     A     |       7       |
    +–––––––––––––––––––––––––––+
    |     B     |       6       |
    +–––––––––––––––––––––––––––+
    |     C     |       6       |
    +–––––––––––+–––––––––––––––+

采纳答案by Wuaner

Guava provides an Iterables.cycle(), coupled with a Multisetfor countingand you're done:

Guava 提供了一个Iterables.cycle(), 加上一个Multiset用于计数,你就完成了:

package com.stackoverflow.so22869350;

import com.google.common.collect.HashMultiset;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Multiset;

import java.util.Iterator;
import java.util.List;

public class Circular<T> {

    private final Multiset<T> counter;

    private final Iterator<T> elements;

    public Circular(final List<T> elements) {
        this.counter = HashMultiset.create();
        this.elements = Iterables.cycle(elements).iterator();
    }

    public T getOne() {
        final T element = this.elements.next();
        this.counter.add(element);
        return element;
    }

    public int getCount(final T element) {
        return this.counter.count(element);
    }

    public static void main(final String[] args) {
        final Circular<String> circular = new Circular<>(Lists.newArrayList("A", "B", "C"));
        for (int i = 0; i < 7; i++) {
            System.out.println(circular.getOne());
        }
        System.out.println("Count for A: " + circular.getCount("A"));
    }
} 

Output:

输出:

A
B
C
A
B
C
A
Count for A: 3

NB:Beware to have proper equals/hashCodefor type T

注意:注意有适当的equals/hashCode类型T

回答by Ashish Shetkar

the above answer is correct, just adding one more simpler way of round robin algorithm with list

上面的答案是正确的,只是在列表中添加了一种更简单的循环算法方法

import java.util.Iterator;
import java.util.List;

public class MyRoundRobin<T> implements Iterable<T> {
      private List<T> coll;
      private int index = 0;

      public MyRoundRobin(List<T> coll) { this.coll = coll; }

      public Iterator<T> iterator() { 
         return new Iterator<T>() {


            @Override
            public boolean hasNext() {
                return true;
            }

            @Override
            public T next() {
                index++;
                if(index>=coll.size()) {
                    index = 0;
                }
                T res = coll.get(index);
                return res;
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }

        };
    }
}