Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 创建不允许重复元素且应允许基于索引的检索的队列_Java_Data Structures - Fatal编程技术网

Java 创建不允许重复元素且应允许基于索引的检索的队列

Java 创建不允许重复元素且应允许基于索引的检索的队列,java,data-structures,Java,Data Structures,我想创建一个不允许重复元素的队列,并且我应该能够基于索引访问该队列的元素。请告诉我应该如何实现此功能?您可以始终使用ArrayList。它有助于基于索引访问元素,并且在添加元素时,始终可以检查ArrayList是否包含要添加的元素。我最初的直觉是使用集合来禁止重复,但元素是集合,而集合没有索引。如果你能找到一种方法来索引集合中的元素,那么这就是我的建议 很明显,Java没有与您的规范和需求相匹配的精确数据结构。与您的需求最接近的可能是。它基本上是一个集合(与您的独特项需求相匹配),其元素按插入顺

我想创建一个不允许重复元素的队列,并且我应该能够基于索引访问该队列的元素。请告诉我应该如何实现此功能?

您可以始终使用ArrayList。它有助于基于索引访问元素,并且在添加元素时,始终可以检查ArrayList是否包含要添加的元素。我最初的直觉是使用集合来禁止重复,但元素是集合,而集合没有索引。如果你能找到一种方法来索引集合中的元素,那么这就是我的建议

很明显,Java没有与您的规范和需求相匹配的精确数据结构。与您的需求最接近的可能是。它基本上是一个集合(与您的独特项需求相匹配),其元素按插入顺序(如队列)保存,要按索引获取元素,您可以使用
Set.toArray()
从集合中获取数组或创建列表(但这会消耗一些额外内存).

不要将其称为队列,因为根据定义,队列只是先进先出的数据结构

根据您的输入值,我认为您应该使用数组和哈希函数。散列使用元素的值确定元素所在的索引,反之亦然,即当给定索引时,它返回其中包含的值

由于您使用的是散列,因此在发生冲突时可以避免重复,即,您可以检查索引中以前是否存在某个值,以及该值是否相同

C++stl有一个很好的set类,尽管我认为java没有。但这一点已经确定,不提供基于索引的检索。

我计划用它来解决我的问题。下面是示例代码

import java.util.concurrent.ConcurrentLinkedQueue;


public class FinalQueue {

    private ConcurrentLinkedQueue<String> queue;

    public FinalQueue()
    {
        queue = new ConcurrentLinkedQueue<String>();
    }

    public synchronized void enqueue(String ipAddress)
    {
        if(!queue.contains(ipAddress))
            queue.add(ipAddress);
    }

    public String dequeue()
    {
        return queue.poll();
    }

    public String toString()
    {
        return "" + queue;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        FinalQueue queue = new FinalQueue();
        queue.enqueue("1.2.3.4");
        queue.enqueue("2.3.4.5");
        queue.enqueue("1.1.1.1");
        queue.enqueue("1.2.3.4");
        System.out.println(queue.toString());
        System.out.println("Dequeue..." + queue.dequeue());
        System.out.println("Dequeue..." + queue.dequeue());
        System.out.println(queue.toString());
    }
}
import java.util.concurrent.ConcurrentLinkedQueue;
公共类最终队列{
私有ConcurrentLinkedQueue队列;
公共最终队列()
{
队列=新的ConcurrentLinkedQueue();
}
公共同步的无效队列(字符串ipAddress)
{
如果(!queue.contains(ipAddress))
queue.add(ipAddress);
}
公共字符串出列()
{
返回queue.poll();
}
公共字符串toString()
{
返回“”+队列;
}
/**
*@param args
*/
公共静态void main(字符串[]args){
FinalQueue=新的FinalQueue();
排队。排队(“1.2.3.4”);
排队。排队(“2.3.4.5”);
排队。排队(“1.1.1.1”);
排队。排队(“1.2.3.4”);
System.out.println(queue.toString());
System.out.println(“Dequeue…”+queue.Dequeue());
System.out.println(“Dequeue…”+queue.Dequeue());
System.out.println(queue.toString());
}
}

所以它根本不是一个队列。您需要什么样的精确访问模式?它将是一个队列,此队列的使用者应该能够从队列中退出队列,但我不会从队列中删除已退出队列的元素,而是在存储在该索引中的元素中设置一个标志。我相信最好为
列表
(可能是
ArrayList')创建一个包装器。通过修改
add`方法来检查重复。因此它不是队列。它是一个线性列表,可能会附加到。对我来说,这听起来像一个数组列表,带有存在性检查。事后想:这也是一个非常糟糕的设计。查找下一个要处理的元素将是O(N)。除非单独维护“下一个”索引,否则不要这样做。在ArrayList中插入每个元素时,我需要扫描整个列表,查看是否存在相同的条目。我应该使用2种数据结构吗?1)一个包含我的对象的搜索键的映射,2)一个包含所有数据的ArrayList,即使这样,你也必须扫描整个列表,看看它是否在那里。我想过使用Map来确定对象是否存在。如果对象不存在,那么我将在Map中存储该对象的“唯一字段”,并在ArrayList中存储完整的对象。这样行吗?对不起,我不太明白你的意思。您能详细说明一下吗?假设我想存储以下类Employee{int-empId,String-name}的实例,这里的“唯一字段”将是“empId”。因此,如果我在内部维护一个包含所有对象的“empId”的映射和一个存储实际对象的ArrayList。每当我想插入一个对象时,它的“empId”应该在Map中被选中。如果不存在,则可以在ArrayList中插入对象,并在Mapset中插入“empId”。toArray()不是一个好选项。因为它将首先将整个集合转换为数组。最好使用迭代器。使用并发java集合通常不是一个好主意。无论如何,您都需要在客户端代码中使用锁。忘了并发集合吧。