Java의 순환 버퍼

Sheeraz Gul 2024년2월15일
Java의 순환 버퍼

이 자습서에서는 배열 및 연결 목록을 사용하여 Java에서 순환 버퍼를 생성하는 방법을 보여줍니다.

Java의 순환 버퍼

순환 버퍼는 큐로 사용되는 배열로 알려져 있습니다. 한 프로세스에서 다른 프로세스로 지속적으로 데이터를 이동하면 해당 데이터를 검색할 시간이 있기 때문에 영구 메모리 위치에 데이터를 저장할 수 없습니다.

따라서 이러한 유형의 데이터를 버퍼, 예를 들어 RAM과 같은 임시 위치에 저장해야 합니다. “링 버퍼"라고도 하는 순환 버퍼는 메모리를 연속적으로 사용할 수 있는 대기열입니다.

순환 버퍼는 선입 선출 FIFO 방식으로 작동하며 배열 또는 연결 목록을 사용하여 구현할 수 있습니다. 이제 배열로 학습을 시작하겠습니다.

배열을 사용하여 Java에서 원형 버퍼 생성

배열을 사용하여 순환 버퍼를 생성하려면 배열에 추가된 요소의 유형을 알 수 없는 생성자에서 빈 배열을 초기화해야 합니다.

두 포인터 headtail은 삽입 및 삭제 작업에 사용됩니다. 여기서 head는 첫 번째 요소이고 tail은 마지막 요소입니다.

java의 순환 버퍼 - 순환 버퍼 배열 배열

이제 inout은 삽입과 삭제를 의미하는 두 가지 주요 작업이 있습니다.

삽입 작업 데모

삽입은 몇 가지 필수 사항이 있는 쉬운 작업입니다.

  1. 시작 시 배열 크기는 0이며 head 위치는 0이고 tail 위치는 -1입니다.

  2. 그런 다음 요소를 삽입할 인덱스에 대해 다음 수식을 사용합니다.

    int index_position = (tail_pointer + 1) % buffer_capacity
    array[index_position] = element;
    
  3. 배열의 크기와 tail 포인터는 배열에 요소를 삽입할 때 1씩 증가합니다.

  4. 배열 크기가 용량과 같으면 더 이상 요소를 추가할 수 없습니다.

삭제 작업 데모

  1. 요소가 head 포인터에서 검색되면 head 포인터에서 1이 증가하고 버퍼 크기에서 1이 감소합니다.

  2. 요소를 삭제할 인덱스에 다음 수식이 사용됩니다.

    int index_position = head_pointer % buffer_capacity;
    Elem element = (Elem) array[index_position];
    

    이제 예를 들어 순환 버퍼의 입력 배열은 다음과 같습니다.

    [7, 2, 5, 3, 4]
    

    요소는 순환 버퍼를 사용하여 순서대로 인쇄됩니다.

    7
    2
    5
    3
    4
    

Java에서 순환 버퍼에 대해 위의 방법을 구현해 봅시다.

package delftstack;

import java.io.*;
import java.lang.*;

class Circular_Buffer {
  // the initial capacity of the buffer
  private int buffer_capacity = 0;
  // the initial size of the buffer
  private int buffer_size = 0;
  // the head pointer
  private int head_pointer = 0;
  // the tail pointer
  private int tail_pointer = -1;
  // the array
  private Object[] demo_array;

  Circular_Buffer(int array_capacity) {
    // initialize the array capacity in the constructor
    this.buffer_capacity = array_capacity;

    // initialize the array
    demo_array = new Object[array_capacity];
  }

  // insertion
  public void Insert(Object array_element) throws Exception {
    // calculate the index to insert the element
    int index = (tail_pointer + 1) % buffer_capacity;

    // increment in the size of the array
    buffer_size++;

    if (buffer_size == buffer_capacity) {
      throw new Exception("Buffer is Overflowen");
    }

    // store the element in the array
    demo_array[index] = array_element;

    // increment the tail pointer
    tail_pointer++;
  }

  // deletion
  public Object Delete() throws Exception {
    // check if the array is empty
    if (buffer_size == 0) {
      throw new Exception("Buffer is empty");
    }

    // calculate the index of the element which is going to be deleted
    int element_index = head_pointer % buffer_capacity;

    // get the element
    Object array_element = demo_array[element_index];

    // increment the head pointer
    head_pointer++;

    // decrement the size of the array
    buffer_size--;

    // return the first element
    return array_element;
  }

  // retrieve the first element
  public Object Retrieve() throws Exception {
    // check if the array is empty
    if (buffer_size == 0) {
      throw new Exception("Buffer is empty");
    }

    // calculate the index of the element to be deleted
    int element_index = head_pointer % buffer_capacity;

    Object array_element = demo_array[element_index];

    return array_element;
  }

  // helper methods
  public boolean isEmpty() {
    return buffer_size == 0;
  }
  public int size() {
    return buffer_size;
  }
}

public class Example {
  public static void main(String[] args) throws Exception {
    // create the Circular Buffer using an array
    Circular_Buffer Array_CircularBuffer = new Circular_Buffer(10);

    // insert elements into the circular buffer
    Array_CircularBuffer.Insert(7);
    Array_CircularBuffer.Insert(2);
    Array_CircularBuffer.Insert(5);
    Array_CircularBuffer.Insert(3);
    Array_CircularBuffer.Insert(4);

    // print the elements with the delete method
    System.out.println("The elements were inserted and "
        + "now printed in the order by deletion:-");
    System.out.println(Array_CircularBuffer.Delete());
    System.out.println(Array_CircularBuffer.Delete());
    System.out.println(Array_CircularBuffer.Delete());
    System.out.println(Array_CircularBuffer.Delete());
    System.out.println(Array_CircularBuffer.Delete());
  }
}

위의 코드에는 두 개의 클래스가 포함되어 있습니다. 하나는 메서드용이고 다른 하나는 작업을 실행하는 기본 클래스용입니다.

첫 번째 클래스에는 요소의 삽입, 삭제 및 검색을 위한 메서드가 포함됩니다. 코드는 순환 버퍼 삽입 및 삭제 작업을 적용하여 요소를 하나씩 인쇄합니다. 출력을 참조하십시오.

The elements were inserted and now printed in the order by deletion:-
7
2
5
3
4

연결 목록을 사용하여 Java에서 순환 버퍼 생성

Java에서 연결 목록을 사용하여 순환 버퍼를 만들려면 일반 노드를 만드는 데 사용할 도우미 클래스를 만들어야 합니다. 배열과 유사하게 삽입 및 삭제를 위해 headtail을 유지합니다. 프로세스는 그림에 나와 있습니다.

java의 순환 버퍼 - 연결 목록 순환 버퍼

삽입 작업 데모

연결 목록을 사용하여 순환 버퍼를 만들기 위한 삽입 단계는 다음과 같습니다.

  1. 처음에 크기는 0이고 headtailnull입니다.
  2. 그런 다음 연결 목록의 꼬리에 요소가 추가됩니다.
  3. 그러면 tail의 참조가 head 포인터로 변경됩니다.
  4. 연결 리스트에 요소가 추가되면 버퍼 크기도 증가합니다.
  5. 배열 크기가 용량과 같으면 더 이상 요소를 추가할 수 없습니다.

삭제 작업 데모

삭제 단계는 다음과 같습니다.

  1. 먼저 head 포인터에서 요소를 검색합니다.

  2. 둘째, head 포인터의 참조를 다음 요소로 변경합니다.

  3. 버퍼 크기는 1 감소합니다.

    이제 예를 들어 연결 목록을 사용하는 순환 버퍼의 입력 배열은 다음과 같습니다.

    [7, 2, 5, 3, 4]
    

    요소는 연결된 목록이 있는 순환 버퍼를 사용하여 순서대로 인쇄됩니다.

    7
    2
    5
    3
    4
    

Java 코드에서 연결 목록을 사용하여 순환 버퍼를 구현해 보겠습니다.

package delftstack;

class Node<Elem> {
  // the data which will be stored in the linked list
  Elem Node_Data;
  // pointer to the next node
  Node<Elem> next_pointer;

  // the constructor will initialize the data in each node
  Node(Elem Node_data) {
    this.Node_Data = Node_data;
  }
}

class LinkedList_CircularBuffer<Elem> {
  // the head node
  Node<Elem> head_element;

  // the tail node
  Node<Elem> tail_element;
  int list_size = 0;
  int list_capacity = 0;

  // the constructor for circular buffer class
  LinkedList_CircularBuffer(int list_capacity) {
    this.list_capacity = list_capacity;
  }

  // insertion
  public void Insert(Elem element) throws Exception {
    // increment in the size when elements
    // are added to the linked list
    list_size++;

    // check the buffer
    if (list_size == list_capacity) {
      throw new Exception("Buffer is Overflowen");
    }

    if (head_element == null) {
      head_element = new Node<>(element);
      tail_element = head_element;
      return;
    }

    // The node element which will be linked
    Node<Elem> temp_element = new Node<>(element);

    // reference the last element to the head node
    temp_element.next_pointer = head_element;

    // update the tail reference to the latest node.
    tail_element.next_pointer = temp_element;

    // update the tail to the latest node, which is added now
    tail_element = temp_element;
  }

  // deletion
  public Elem Delete() throws Exception {
    // check the buffer
    if (list_size == 0) {
      throw new Exception("The Buffer is empty");
    }
    // get the element
    Elem element = head_element.Node_Data;

    // update the head pointer
    head_element = head_element.next_pointer;

    // update the tail reference to the head pointer
    tail_element.next_pointer = head_element;

    // decrement in the size
    list_size--;
    if (list_size == 0) {
      // remove any references present when the buffer is null
      head_element = tail_element = null;
    }
    return element;
  }

  // retrieve the head element without deleting it
  public Elem Retrieve() throws Exception {
    // check the buffer
    if (list_size == 0) {
      throw new Exception("Empty Buffer");
    }
    // get the element
    Elem element = head_element.Node_Data;
    return element;
  }

  // helper methods
  public boolean isEmpty() {
    return list_size == 0;
  }
  public int size() {
    return list_size;
  }
}

public class Example {
  public static void main(String[] args) throws Exception {
    // create the Circular Buffer using Linked List
    LinkedList_CircularBuffer<Integer> LL_CircularBuffer = new LinkedList_CircularBuffer<>(10);

    // insert elements to the circular Buffer
    LL_CircularBuffer.Insert(7);
    LL_CircularBuffer.Insert(2);
    LL_CircularBuffer.Insert(5);
    LL_CircularBuffer.Insert(3);
    LL_CircularBuffer.Insert(4);

    // printing the elements with the method delete
    System.out.println("The elements were inserted and "
        + "now printed in the order by deletion:-");
    System.out.println(LL_CircularBuffer.Delete());
    System.out.println(LL_CircularBuffer.Delete());
    System.out.println(LL_CircularBuffer.Delete());
    System.out.println(LL_CircularBuffer.Delete());
    System.out.println(LL_CircularBuffer.Delete());
  }
}

위의 코드는 연결 목록 작업을 수행하는 일반 노드 클래스를 만들고 삽입, 삭제 및 검색 작업을 수행하는 메서드를 만듭니다.

이 코드는 연결된 목록을 사용하여 순환 버퍼를 만들고 입력 목록 요소를 하나씩 인쇄합니다. 아래 출력을 참조하세요.

The elements were inserted and now printed in the order by deletion:-
7
2
5
3
4
작가: Sheeraz Gul
Sheeraz Gul avatar Sheeraz Gul avatar

Sheeraz is a Doctorate fellow in Computer Science at Northwestern Polytechnical University, Xian, China. He has 7 years of Software Development experience in AI, Web, Database, and Desktop technologies. He writes tutorials in Java, PHP, Python, GoLang, R, etc., to help beginners learn the field of Computer Science.

LinkedIn Facebook

관련 문장 - Java Buffer