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

Wua*_*ner 9 java iterator load-balancing round-robin circular-list

场景:


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

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

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


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

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


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

任何回应将不胜感激.

问候.


更新


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


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


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

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


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


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

小智 22

番石榴提供了一个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"));
    }
} 
Run Code Online (Sandbox Code Playgroud)

输出:

A
B
C
A
B
C
A
Count for A: 3
Run Code Online (Sandbox Code Playgroud)

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


小智 7

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

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() {
                if (index >= coll.size()) {
                    index = 0;
                }
                T res = coll.get(index++);
                return res;
            }
            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)