Java中集合的size()的时间复杂度是多少?

Java中集合的size()的时间复杂度是多少?,java,size,set,hashset,treeset,Java,Size,Set,Hashset,Treeset,我知道,这似乎是一个愚蠢的问题,你可能会认为任何集合上size()的时间复杂度都是O(1)——但我发现我的代码中的“优化”需要调用size()实际上会减慢速度 那么,Java中集合的size()的时间复杂度是多少 我的代码是一个递归算法的实现,用于查找图中的最大团(不重要)。基本上,优化只检查两个集合的大小是否相等(这些集合以任何方式构造),如果大小相等,则只允许再进行一次递归调用(在此之后停止递归) 以下是我的代码的(简化)版本: private static void rec

我知道,这似乎是一个愚蠢的问题,你可能会认为任何集合上size()的时间复杂度都是O(1)——但我发现我的代码中的“优化”需要调用size()实际上会减慢速度

那么,Java中集合的size()的时间复杂度是多少

我的代码是一个递归算法的实现,用于查找图中的最大团(不重要)。基本上,优化只检查两个集合的大小是否相等(这些集合以任何方式构造),如果大小相等,则只允许再进行一次递归调用(在此之后停止递归)

以下是我的代码的(简化)版本:

        private static void recursivelyFindMaximalCliques(Set<Integer> subGraph, Set<Integer> candidates, Set<Integer> notCandidates) {
    boolean noFurtherCliques = false;

    Iterator<Integer> candidateIterator = candidates.iterator();
    while (candidateIterator.hasNext()) {
        int nextCandidate = candidateIterator.next();
        candidateIterator.remove();
        subGraph.add(nextCandidate);

        Set<Integer> neighbors = getNeighbors(nextCandidate);
        Set<Integer> newCandidates = calculateIntersection(candidates, neighbors);
        Set<Integer> newNotCandidates = calculateIntersection(notCandidates, neighbors);

        //if (newCandidates.size() == candidates.size())
        //  noFurtherCliques = true;
        recursivelyFindMaximalCliques(subGraph, newCandidates, newNotCandidates);
        //if (noFurtherCliques)
        //  return;

        subGraph.set.remove(nextCandidate);
        notCandidates.set.add(nextCandidate);
    }
}
private static void recursivelyFindMaximalCliques(集合子图、集合候选对象、集合Not候选对象){
布尔派系=假;
迭代器candidateIterator=候选项。迭代器();
while(candidateInterator.hasNext()){
int-nextCandidate=candidateInterator.next();
CandidateInterator.remove();
子图。添加(下一个条件);
设置邻居=获取邻居(nextCandidate);
设置新候选项=计算区间(候选项、邻居);
Set newNotCandidates=calculateIntersection(notCandidates,neights);
//if(newCandidates.size()==candidates.size())
//无派系=正确;
递归查找最大团(子图,newCandidates,newNotCandidates);
//if(无集团)
//返回;
子图.set.remove(nextCandidate);
notCandidates.set.add(nextCandidate);
}
}
我已经注释掉的行是有问题的行-您可以看到它们检查集合newCandidates和candidates是否大小相同,如果大小相同,递归只允许更深一层

当这些行没有注释时,代码运行速度会慢10%——无论使用的集合是HashSet、TreeSet还是LinkedHashSet,都是如此。这毫无意义,因为这些行确保递归调用更少

我唯一可以假设的是,对集合调用size()需要很长时间。在Java中对集合调用size()是否需要比O(1)更长的时间

编辑

因为有人问过,这里是calculateIntersection():

private static IntegerSet calculateIntersection(Set setA,Set setB){
如果(setA.size()==0 | | setB.size()==0)
返回新集合();
Set intersection=new Set();//将其替换为TreeSet、HashSet或LinkedHashSet,以使用的为准
交叉点。addAll(setA);
交叉口。保留(后退);
折返交叉口;
}
第二次编辑 这是完整的代码,如果你喜欢的话。我犹豫是否要发布它,因为它又长又脏,但人们问,所以它在这里:

public class CliqueFindingAlgorithm {

private static class IntegerSet {
    public Set<Integer> set = new TreeSet<Integer>();  //Or whatever Set is being used
}


private static ArrayList<IntegerSet> findMaximalCliques(UndirectedGraph graph) {
    ArrayList<IntegerSet> cliques = new ArrayList<IntegerSet>();
    IntegerSet subGraph = new IntegerSet();
    IntegerSet candidates = new IntegerSet();
    IntegerSet notCandidates = new IntegerSet();

    for (int vertex = 0; vertex < graph.getNumVertices(); vertex++) {
        candidates.set.add(vertex);
    }

    recursivelyFindMaximalCliques(cliques, graph, subGraph, candidates, notCandidates);
    return cliques;
}


private static void recursivelyFindMaximalCliques(ArrayList<IntegerSet> cliques, UndirectedGraph graph, 
        IntegerSet subGraph, IntegerSet candidates, IntegerSet notCandidates) {
    boolean noFurtherCliques = false;

    Iterator<Integer> candidateIterator = candidates.set.iterator();
    while (candidateIterator.hasNext()) {
        int nextCandidate = candidateIterator.next();
        candidateIterator.remove();
        subGraph.set.add(nextCandidate);

        IntegerSet neighbors = new IntegerSet();
        neighbors.set = graph.getNeighbors(nextCandidate);
        IntegerSet newCandidates = calculateIntersection(candidates, neighbors);
        IntegerSet newNotCandidates = calculateIntersection(notCandidates, neighbors);

        if (newCandidates.set.size() == candidates.set.size())
            noFurtherCliques = true;
        recursivelyFindMaximalCliques(cliques, graph, subGraph, newCandidates, newNotCandidates);
        if (noFurtherCliques)
            return;

        subGraph.set.remove(nextCandidate);
        notCandidates.set.add(nextCandidate);
    }

    if (notCandidates.set.isEmpty()) {
        IntegerSet clique = new IntegerSet();
        clique.set.addAll(subGraph.set);
        cliques.add(clique);
    }
}


private static IntegerSet calculateIntersection(IntegerSet setA, IntegerSet setB) {
    if (setA.set.size() == 0 || setB.set.size() == 0)
        return new IntegerSet();

    IntegerSet intersection = new IntegerSet();
    intersection.set.addAll(setA.set);
    intersection.set.retainAll(setB.set);
    return intersection;
}
公共类cliquefinding算法{
私有静态类整数集{
public Set Set=new TreeSet();//或正在使用的任何集合
}
私有静态ArrayList findMaximalCliques(无向图){
ArrayList cliques=新的ArrayList();
整数集子图=新整数集();
整数集候选者=新整数集();
IntegerSet notCandidates=新的IntegerSet();
对于(int-vertex=0;顶点
}

公共类无向图{
//------------------------------私有变量------------------------------
私人ArrayList邻里主义者;
私人国际努梅德斯;
//------------------------------------常数------------------
//------------------------------构造器------------------------------
公共无向图(整数){
this.neightrlists=新的数组列表(numVertices);
此值为0.numEdges=0;
对于(int i=0;ipublic class CliqueFindingAlgorithm {

private static class IntegerSet {
    public Set<Integer> set = new TreeSet<Integer>();  //Or whatever Set is being used
}


private static ArrayList<IntegerSet> findMaximalCliques(UndirectedGraph graph) {
    ArrayList<IntegerSet> cliques = new ArrayList<IntegerSet>();
    IntegerSet subGraph = new IntegerSet();
    IntegerSet candidates = new IntegerSet();
    IntegerSet notCandidates = new IntegerSet();

    for (int vertex = 0; vertex < graph.getNumVertices(); vertex++) {
        candidates.set.add(vertex);
    }

    recursivelyFindMaximalCliques(cliques, graph, subGraph, candidates, notCandidates);
    return cliques;
}


private static void recursivelyFindMaximalCliques(ArrayList<IntegerSet> cliques, UndirectedGraph graph, 
        IntegerSet subGraph, IntegerSet candidates, IntegerSet notCandidates) {
    boolean noFurtherCliques = false;

    Iterator<Integer> candidateIterator = candidates.set.iterator();
    while (candidateIterator.hasNext()) {
        int nextCandidate = candidateIterator.next();
        candidateIterator.remove();
        subGraph.set.add(nextCandidate);

        IntegerSet neighbors = new IntegerSet();
        neighbors.set = graph.getNeighbors(nextCandidate);
        IntegerSet newCandidates = calculateIntersection(candidates, neighbors);
        IntegerSet newNotCandidates = calculateIntersection(notCandidates, neighbors);

        if (newCandidates.set.size() == candidates.set.size())
            noFurtherCliques = true;
        recursivelyFindMaximalCliques(cliques, graph, subGraph, newCandidates, newNotCandidates);
        if (noFurtherCliques)
            return;

        subGraph.set.remove(nextCandidate);
        notCandidates.set.add(nextCandidate);
    }

    if (notCandidates.set.isEmpty()) {
        IntegerSet clique = new IntegerSet();
        clique.set.addAll(subGraph.set);
        cliques.add(clique);
    }
}


private static IntegerSet calculateIntersection(IntegerSet setA, IntegerSet setB) {
    if (setA.set.size() == 0 || setB.set.size() == 0)
        return new IntegerSet();

    IntegerSet intersection = new IntegerSet();
    intersection.set.addAll(setA.set);
    intersection.set.retainAll(setB.set);
    return intersection;
}
public class UndirectedGraph {

// ------------------------------ PRIVATE VARIABLES ------------------------------

private ArrayList<TreeMap<Integer, Double>> neighborLists;
private int numEdges;


// ------------------------------ CONSTANTS ------------------------------  

// ------------------------------ CONSTRUCTORS ------------------------------

public UndirectedGraph(int numVertices) {
    this.neighborLists = new ArrayList<TreeMap<Integer, Double>>(numVertices);
    this.numEdges = 0;
    for (int i = 0; i < numVertices; i++) {
        this.neighborLists.add(new TreeMap<Integer, Double>());
    }
}


// ------------------------------ PUBLIC METHODS ------------------------------


public void addEdge(int vertexA, int vertexB, double edgeWeight) {
    TreeMap<Integer, Double> vertexANeighbors = this.neighborLists.get(vertexA);
    TreeMap<Integer, Double> vertexBNeighbors = this.neighborLists.get(vertexB);

    vertexANeighbors.put(vertexB, edgeWeight);
    vertexBNeighbors.put(vertexA, edgeWeight);
    this.numEdges++;
}


public List<Integer> computeCommonNeighbors(int vertexA, int vertexB) {
    List<Integer> commonNeighbors = new ArrayList<Integer>();
    Iterator<Integer> iteratorA = this.getNeighbors(vertexA).iterator();
    Iterator<Integer> iteratorB = this.getNeighbors(vertexB).iterator();

    if (iteratorA.hasNext() && iteratorB.hasNext()) {
        int nextNeighborA = iteratorA.next();
        int nextNeighborB = iteratorB.next();
        while(true) {

            if (nextNeighborA == nextNeighborB) {
                commonNeighbors.add(nextNeighborA);
                if (iteratorA.hasNext() && iteratorB.hasNext()) {
                    nextNeighborA = iteratorA.next();
                    nextNeighborB = iteratorB.next();
                }
                else
                    break;
            }

            else if (nextNeighborA < nextNeighborB) {
                if (iteratorA.hasNext())
                    nextNeighborA = iteratorA.next();
                else
                    break;
            }

            else if (nextNeighborB < nextNeighborA) {
                if (iteratorB.hasNext())
                    nextNeighborB = iteratorB.next();
                else
                    break;
            }
        }
    }

    return commonNeighbors;
}

// ------------------------------ PRIVATE METHODS ------------------------------

private class EdgeIterator implements Iterator<int[]> {

    private int vertex;
    private int[] nextPair;
    private Iterator<Integer> neighborIterator;

    public EdgeIterator() {
        this.vertex = 0;
        this.neighborIterator = neighborLists.get(0).keySet().iterator();
        this.getNextPair();
    }

    public boolean hasNext() {
        return this.nextPair != null;
    }

    public int[] next() {
        if (this.nextPair == null)
            throw new NoSuchElementException();
        int[] temp = this.nextPair;
        this.getNextPair();
        return temp;
    }

    public void remove() {
        throw new UnsupportedOperationException();
    }

    private void getNextPair() {
        this.nextPair = null;

        while (this.nextPair == null && this.neighborIterator != null) {
            while (this.neighborIterator.hasNext()) {
                int neighbor = this.neighborIterator.next();

                if (this.vertex <= neighbor) {
                    this.nextPair = new int[] {vertex, neighbor};
                    return;
                }
            }

            this.vertex++;
            if (this.vertex < getNumVertices())
                this.neighborIterator = neighborLists.get(this.vertex).keySet().iterator();
            else
                this.neighborIterator = null;
        }   
    }
}

// ------------------------------ GETTERS & SETTERS ------------------------------

public int getNumEdges() {
    return this.numEdges;
}


public int getNumVertices() {
    return this.neighborLists.size();
}


public Double getEdgeWeight(int vertexA, int vertexB) {
    return this.neighborLists.get(vertexA).get(vertexB);
}


public Set<Integer> getNeighbors(int vertex) {
    return Collections.unmodifiableSet(this.neighborLists.get(vertex).keySet());
}


public Iterator<int[]> getEdgeIterator() {
    return new EdgeIterator();
}
//HashSet
public int size() {
    return map.size();
}

//Hashmap
public int size() {
    return size;
}