java中正确使用的数据结构是什么?

发布于 2024-10-12 07:15:32 字数 66 浏览 6 评论 0原文

我想将整数保存在数据结构中,但不知道数字 我可能得到的整数。 我希望数据库是 FIFO 类型的。 什么最适合这个目的?

I want to save integers in a data structure, but without knowing the number
of integers i might get.
I want the database to be of FIFO kind.
What is best for this purpose?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一张白纸 2024-10-19 07:15:32

除了使用数据库之外,如果您只有一些整数,您可以将它们写入一个普通文件。普通文件保留顺序,但删除条目的成本可能很高。

您可以使用普通文件在大约 0.1 秒内写入/重写 100 万个整数。

TIntArrayList 是 int 原语的一个有效集合。它就像 @JPelletier 的建议,但包装了一个 int[]。一百万个 int 值应占用大约 4 MB 的内存或磁盘。

编辑:这表明对于 100 万个数字来说 ArrayList 是一个糟糕的选择。主要是因为remove(0)是O(n)而不是O(1

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

// based on http://www.cs.princeton.edu/introcs/43stack/RingBuffer.java.html
public class IntRingBuffer {
    private final int[] a;       // queue elements
    private int N = 0;           // number of elements on queue
    private int first = 0;       // index of first element of queue
    private int last  = 0;       // index of next available slot

    // cast needed since no generic array creation in Java
    public IntRingBuffer(int capacity) {
        a = new int[capacity];
    }

    public boolean isEmpty() { return N == 0; }
    public int size()        { return N;      }

    public void enqueue(int item) {
        if (N == a.length) { throw new RuntimeException("Ring buffer overflow"); }
        a[last] = item;
        last = (last + 1) % a.length;     // wrap-around
        N++;
    }

    // remove the least recently added item - doesn't check for underflow
    public int dequeue() {
        if (isEmpty()) { throw new RuntimeException("Ring buffer underflow"); }
        int item = a[first];
        N--;
        first = (first + 1) % a.length;   // wrap-around
        return item;
    }

    public static void main(String... args) {
        int size = 1000000;
        {
        long start = System.nanoTime();
        IntRingBuffer list = new IntRingBuffer(size);
        for(int i=0;i< size;i++)
            list.enqueue(i);
        for(int i=0;i< size;i++)
            list.dequeue();
        long time = System.nanoTime() - start;
        System.out.println(list.getClass().getSimpleName()+": Took "+time/1000/1000+" ms to add/remove "+size+" elements");
        }
        {
        long start = System.nanoTime();
        List<Integer> list = new LinkedList<Integer>();
        for(int i=0;i< size;i++)
            list.add(i);
        for(int i=0;i< size;i++)
            list.remove(0);
        long time = System.nanoTime() - start;
        System.out.println(list.getClass().getSimpleName()+": Took "+time/1000/1000+" ms to add/remove "+size+" elements");
        }
        {
        long start = System.nanoTime();
        List<Integer> list = new ArrayList<Integer>();
        for(int i=0;i< size;i++)
            list.add(i);
        for(int i=0;i< size;i++)
            list.remove(0);
        long time = System.nanoTime() - start;
        System.out.println(list.getClass().getSimpleName()+": Took "+time/1000/1000+" ms to add/remove "+size+" elements");
        }

    }
}

)

IntRingBuffer: Took 31 ms to add/remove 1000000 elements
LinkedList: Took 252 ms to add/remove 1000000 elements
ArrayList: Took 325832 ms to add/remove 1000000 elements

Apart from using a database, if you just have a number of intergers you could write them to a plain file. Plain files retain order, however removing entries can be expensive.

You can write/rewrite 1 million integers in about 0.1 seconds using a plain file.

An efficient collecton for int primitives is TIntArrayList. Its like @JPelletier's suggestion but wraps a int[]. A million int values should take about 4 MB of memory or disk.

EDIT: This shows that for 1 million numbers ArrayList is a bad choice. Mainly because remove(0) is O(n) rather than O(1)

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

// based on http://www.cs.princeton.edu/introcs/43stack/RingBuffer.java.html
public class IntRingBuffer {
    private final int[] a;       // queue elements
    private int N = 0;           // number of elements on queue
    private int first = 0;       // index of first element of queue
    private int last  = 0;       // index of next available slot

    // cast needed since no generic array creation in Java
    public IntRingBuffer(int capacity) {
        a = new int[capacity];
    }

    public boolean isEmpty() { return N == 0; }
    public int size()        { return N;      }

    public void enqueue(int item) {
        if (N == a.length) { throw new RuntimeException("Ring buffer overflow"); }
        a[last] = item;
        last = (last + 1) % a.length;     // wrap-around
        N++;
    }

    // remove the least recently added item - doesn't check for underflow
    public int dequeue() {
        if (isEmpty()) { throw new RuntimeException("Ring buffer underflow"); }
        int item = a[first];
        N--;
        first = (first + 1) % a.length;   // wrap-around
        return item;
    }

    public static void main(String... args) {
        int size = 1000000;
        {
        long start = System.nanoTime();
        IntRingBuffer list = new IntRingBuffer(size);
        for(int i=0;i< size;i++)
            list.enqueue(i);
        for(int i=0;i< size;i++)
            list.dequeue();
        long time = System.nanoTime() - start;
        System.out.println(list.getClass().getSimpleName()+": Took "+time/1000/1000+" ms to add/remove "+size+" elements");
        }
        {
        long start = System.nanoTime();
        List<Integer> list = new LinkedList<Integer>();
        for(int i=0;i< size;i++)
            list.add(i);
        for(int i=0;i< size;i++)
            list.remove(0);
        long time = System.nanoTime() - start;
        System.out.println(list.getClass().getSimpleName()+": Took "+time/1000/1000+" ms to add/remove "+size+" elements");
        }
        {
        long start = System.nanoTime();
        List<Integer> list = new ArrayList<Integer>();
        for(int i=0;i< size;i++)
            list.add(i);
        for(int i=0;i< size;i++)
            list.remove(0);
        long time = System.nanoTime() - start;
        System.out.println(list.getClass().getSimpleName()+": Took "+time/1000/1000+" ms to add/remove "+size+" elements");
        }

    }
}

Prints

IntRingBuffer: Took 31 ms to add/remove 1000000 elements
LinkedList: Took 252 ms to add/remove 1000000 elements
ArrayList: Took 325832 ms to add/remove 1000000 elements
野味少女 2024-10-19 07:15:32

您可以使用 JDBC 访问的任何关系数据库:MySQL、PostgreSQL、Oracle、SQLServer、DB2、Informix、Interbase、Firebird、Ingress,应有尽有。

如果您正在寻找轻量级的东西,可以查看 SQLite 的 Java API

Any relational DataBase you could access with JDBC: MySQL, PostgreSQL, Oracle, SQLServer, DB2, Informix, Interbase, Firebird, Ingress, you name it.

If you are looking for something lightweight, you can have a look at SQLite's API for Java.

北渚 2024-10-19 07:15:32

我不认为真的存在“先进先出数据库”这样的东西。数据库通常允许您使用某种索引方案以任何所需的顺序访问数据。您可以通过将序列号附加到每条记录并按顺序读取它们来在数据库中实现 FIFO 队列。我曾经使用过的任何数据库都可以做到这一点。

也许简单的答案是 Pablo 给出的:使用任何关系数据库。选择 MySQL 或 Postgres 等免费软件之一,使用它并了解它们的用途。

I don't think there's really such a thing as a "FIFO database". A database normally allows you to access data in any desired order using some sort of indexing scheme. You could implement a FIFO queue in a database by attaching sequence numbers to each record and reading them in order. Any database I've ever used would be capable of that.

Perhaps the simple answer is that given by Pablo: use any relational database. Pick one of the free ones like MySQL or Postgres, play with it, and learn what they do.

两相知 2024-10-19 07:15:32

您真的是指数据库吗?因为您可以使用 ArrayList 来实现:

ArrayList<Integer> array = new ArrayList<Integer>();
array.add(3);
array.add(4);
array.add(5); // Appends to the end of this list

int myInt = array.remove(0); // Return first element

如果您确实需要数据库,您能给我们更多关于您想要做什么的详细信息吗?

[编辑]
我建议您阅读:Java 最佳实践 – Vector 与 ArrayList与 HashSet 谢谢!

Do you really mean a Database? Because you can use an ArrayList for that:

ArrayList<Integer> array = new ArrayList<Integer>();
array.add(3);
array.add(4);
array.add(5); // Appends to the end of this list

int myInt = array.remove(0); // Return first element

If you really need a database, can you give us more details on what you want to do?

[EDIT]
I recommend you to read: Java Best Practices – Vector vs ArrayList vs HashSet Thanks!

娇女薄笑 2024-10-19 07:15:32

听起来你在谈论队列。查看 JMS,看看这是否是您正在寻找的概念。虽然对于如此简单的任务来说,它看起来像是一个大工具,但它会为您提供 FIFO 的持久(到您想要的任何数据库)功能。

Sounds like you're talking about a queue. Look at JMS and see if that's the concept you're looking for. While it may seem like a big tool for such a simple task, it will give you FIFO in a persisted (to any database you wish) functionality.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文