c# - 您将如何用 Java 或 C# 编写高效的循环缓冲区?

标签 c# java class-design

我想要一个实现固定大小的简单类 circular buffer .它应该是高效的、易于理解的、通用类型的。

目前不需要 MT-capable .以后可以随时加锁,反正不会是高并发的。

方法应该是:.Add() 我猜是 .List(),我在其中检索所有条目。转念一想,检索我认为应该通过索引器来完成。在任何时候我都希望能够通过 index 检索缓冲区中的任何元素。但请记住,从一个时刻到下一个 Element[n] 可能会有所不同,因为 循环缓冲区 会填满并翻转。这不是一个堆栈,它是一个循环缓冲区。

关于“溢出”:我希望内部会有一个数组来保存项目,随着时间的推移,headtail缓冲区将围绕该固定数组旋转。但这对用户来说应该是不可见的。不应有外部可检测的“溢出”事件或行为。

这不是学校作业 - 它最常用于 MRU cache或固定大小的事务或事件日志。

最佳答案

我会使用 T 数组、头指针和尾指针,以及添加和获取方法。

喜欢:(Bug 搜索留给用户)

// Hijack these for simplicity
import java.nio.BufferOverflowException;
import java.nio.BufferUnderflowException;

public class CircularBuffer<T> {

  private T[] buffer;

  private int tail;

  private int head;

  @SuppressWarnings("unchecked")
  public CircularBuffer(int n) {
    buffer = (T[]) new Object[n];
    tail = 0;
    head = 0;
  }

  public void add(T toAdd) {
    if (head != (tail - 1)) {
        buffer[head++] = toAdd;
    } else {
        throw new BufferOverflowException();
    }
    head = head % buffer.length;
  }

  public T get() {
    T t = null;
    int adjTail = tail > head ? tail - buffer.length : tail;
    if (adjTail < head) {
        t = (T) buffer[tail++];
        tail = tail % buffer.length;
    } else {
        throw new BufferUnderflowException();
    }
    return t;
  }

  public String toString() {
    return "CircularBuffer(size=" + buffer.length + ", head=" + head + ", tail=" + tail + ")";
  }

  public static void main(String[] args) {
    CircularBuffer<String> b = new CircularBuffer<String>(3);
    for (int i = 0; i < 10; i++) {
        System.out.println("Start: " + b);
        b.add("One");
        System.out.println("One: " + b);
        b.add("Two");
        System.out.println("Two: " + b);
        System.out.println("Got '" + b.get() + "', now " + b);

        b.add("Three");
        System.out.println("Three: " + b);
        // Test Overflow
        // b.add("Four");
        // System.out.println("Four: " + b);

        System.out.println("Got '" + b.get() + "', now " + b);
        System.out.println("Got '" + b.get() + "', now " + b);
        // Test Underflow
        // System.out.println("Got '" + b.get() + "', now " + b);

        // Back to start, let's shift on one
        b.add("Foo");
        b.get();
    }
  }
}

关于c# - 您将如何用 Java 或 C# 编写高效的循环缓冲区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9595958/

相关文章:

c# - 有没有办法在 java 中使用类似于 c# 's at quoting (@"") 的东西

java - 从内部类 StackofStacks<T> 访问外部类

Java SHA256 生成与 Python 中不同的哈希值

c++ - 如何在另一个线程中执行一个方法?

c# DAL类和业务层类

c# - 将度/分/秒转换为小数坐标

c# - 写入在 Excel 中打开的文件

oop - 如何大海捞针?

c# - 棘手的算法......在嵌套的 HashSets 中找到子集的多个组合?

java - 如何为我在 java 上编写的 Selenium 测试增加 travis-ci 中的超时?