一万字关于java数据结构堆的讲解,让你从入门到精通

2023-10-27

目录

java类和接口总览

队列(Queue)

1. 概念

2. 队列的使用

以下是一些常用的队列操作:

1.入队操作

2.出队操作

3.判断队列是否为空

4.获取队列大小

5.其它

优先级队列(堆)

1. 优先级队列概念

Java中的PriorityQueue具有以下特点

2.常用的PriorityQueue操作

1.PriorityQueue的创建

2.插入元素

3.删除具有最高优先级的元素

4.查找具有最高优先级的元素

5.其它

3. 优先级队列的模拟实现

1.堆的概念

2.堆的性质

3.堆的存储方式

4.堆的创建

1.如何把给定的一棵二叉树,变成最小堆或者最大堆

以变成最大堆为例

2.时间复杂度分析

建堆的时间复杂度

 5.堆的删除

 6.用堆模拟实现优先级队列

7.常用接口介绍

1.关于PriorityQueue的使用注意事项

1. 优先级队列的构造

2. 插入/删除/获取优先级最高的元素                                           

完结撒花✿✿ヽ(°▽°)ノ✿


java类和接口总览

队列(Queue)


1. 概念

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First
In First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出队列:进行删除操作的一端称为队头(Head/Front)

2. 队列的使用


在Java中,Queue是个接口,底层是通过链表实现的
 

Java中提供了多种队列(Queue)的实现,如LinkedList、ArrayDeque、PriorityQueue等,可以根据不同的需求选择适合的实现类。

以下是一些常用的队列操作:

1.入队操作

入队操作:使用add()或offer()方法将元素添加到队列的末尾。add()方法如果添加失败会抛出异常,而offer()方法则会返回一个boolean值表示添加是否成功。

Queue<Integer> queue = new LinkedList<>();
queue.add(1);
queue.offer(2);

2.出队操作

出队操作:使用poll()或remove()方法从队列的头部获取并移除元素。poll()方法如果队列为空则会返回null,而remove()方法则会抛出异常。

Queue<Integer> queue = new LinkedList<>();
queue.add(1);
queue.add(2);
int item = queue.poll(); // item的值为1
int item2 = queue.remove(); // item2的值为2

3.判断队列是否为空

判断队列是否为空:使用isEmpty()方法判断队列是否为空。

Queue<Integer> queue = new LinkedList<>();
queue.add(1);
boolean isEmpty = queue.isEmpty(); // isEmpty的值为false

4.获取队列大小

获取队列大小:使用size()方法获取队列的大小。

Queue<Integer> queue = new LinkedList<>();
queue.add(1);
queue.add(2);
int size = queue.size(); // size的值为2

5.其它

除了以上常用的操作外,Java的Queue接口还提供了其他一些方法,如element()方法用于获取队列的头元素但不移除,peek()方法用于获取队列头元素但不移除且判断队列是否为空等。可以根据具体需求选择适合的方法使用。


  

优先级队列(堆)

1. 优先级队列概念

前面介绍过队列,队列是一种先进先出(FIFO)的数据结构,但有些情况下,操作的数据可能带有优先级,一般出队列时,可能需要优先级高的元素先出队列,该中场景下,使用队列显然不合适,比如:在手机上玩游戏的时候,如果有来电,那么系统应该优先处理打进来的电话;初中那会班主任排座位时可能会让成绩好的同学先挑座位。
在这种情况下,数据结构应该提供两个最基本的操作,一个是返回最高优先级对象,一个是添加新的对象。这种数据结构就是优先级队列(Priority Queue)。堆实现了Queue这个接口,可以把它当做优先级队列

Java中的优先级队列(PriorityQueue)是一种特殊的队列,它使用二叉堆实现。在优先级队列中,每个元素都有一个优先级,优先级越高的元素在队列中的位置越靠前。

Java中的PriorityQueue具有以下特点

插入操作:向PriorityQueue中插入元素时,会根据元素的优先级确定其位置。如果新插入的元素的优先级高于当前队列中的最高优先级元素,则新元素将成为队列中的最高优先级元素。
删除操作:从PriorityQueue中删除元素时,会删除具有最高优先级的元素。如果队列中有多个具有相同最高优先级的元素,则会按照它们在队列中的顺序删除。
可查找操作:PriorityQueue支持查找操作,可以查找具有最高优先级的元素,或者查找具有指定优先级的元素。

2.常用的PriorityQueue操作

以下是一些常用的PriorityQueue操作

1.PriorityQueue的创建

在Java中,PriorityQueue可以使用以下代码创建:

PriorityQueue<Integer> pq = new PriorityQueue<>();

2.插入元素

可以使用add()方法向PriorityQueue中插入元素,例如:

pq.add(3);
pq.add(1);
pq.add(2);

3.删除具有最高优先级的元素

可以使用poll()方法从PriorityQueue中删除具有最高优先级的元素,例如:

int max = pq.poll(); // max = 3

4.查找具有最高优先级的元素

可以使用peek()方法查找具有最高优先级的元素,例如:

java
int max = pq.peek(); // max = 3

5.其它

除了默认的PriorityQueue外,Java还提供了一些其他类型的PriorityQueue,例如ArrayDeque、LinkedBlockingDeque等。这些PriorityQueue的实现方式略有不同,可以根据实际需求选择适合的类型。

3. 优先级队列的模拟实现

JDK1.8中的PriorityQueue底层使用了堆这种数据结构,而堆实际就是在完全二叉树的基础上进行了一些调整,本质上堆是一棵顺序存储的二叉树

Java中的优先级队列(PriorityQueue)是使用二叉堆实现的一种数据结构。二叉堆是一种特殊的树形数据结构,其中每个节点都满足堆的性质:根节点的值小于或等于其子节点的值(最大堆)或根节点的值大于或等于其子节点的值(最小堆)。

虽然Java中的PriorityQueue是使用二叉堆实现的,但我们可以使用其他数据结构来模拟实现优先级队列。

下面是一种使用数组实现优先级队列的示例代码:

public class PriorityQueue<T extends Comparable<T>> {
    private int[] heap;
    private int size;

    public PriorityQueue(int capacity) {
        heap = new int[capacity + 1];
    }

    public void enqueue(T value) {
        if (size == heap.length - 1) {
            resize();
        }
        int index = size;
        heap[index] = value.compareTo(((T) heap[index - 1])) > 0 ? value : heap[index - 1];
        upHeap(index);
        size++;
    }

    public T dequeue() {
        if (size == 0) {
            throw new IllegalStateException("Priority queue is empty");
        }
        T max = (T) heap[0];
        heap[0] = heap[size - 1];
        size--;
        downHeap(0);
        return max;
    }

    private void resize() {
        int[] newHeap = new int[heap.length * 2];
        System.arraycopy(heap, 0, newHeap, 0, heap.length);
        heap = newHeap;
    }

    private void upHeap(int index) {
        while (index > 0) {
            int parentIndex = (index - 1) / 2;
            if (heap[parentIndex].compareTo((T) heap[index]) <= 0) {
                break;
            }
            swap(parentIndex, index);
            index = parentIndex;
        }
    }

    private void downHeap(int index) {
        int size = heap.length - 1;
        while (true) {
            int leftChildIndex = 2 * index + 1;
            int rightChildIndex = 2 * index + 2;
            int largestIndex = index;
            if (leftChildIndex < size && heap[leftChildIndex].compareTo((T) heap[largestIndex]) > 0) {
                largestIndex = leftChildIndex;
            }
            if (rightChildIndex < size && heap[rightChildIndex].compareTo((T) heap[largestIndex]) > 0) {
                largestIndex = rightChildIndex;
            }
            if (largestIndex == index) {
                break;
            }
            swap(index, largestIndex);
            index = largestIndex;
        }
    }

    private void swap(int i, int j) {
        Object temp = heap[i];
        heap[i] = heap[j];
        heap[j] = temp;
    }
}

注:该代码定义了一个泛型的PriorityQueue类,支持向队列中插入元素(enqueue)和从队列中删除元素(dequeue)的操作。PriorityQueue使用一个数组来模拟二叉堆,通过调整数组元素的位置来维护堆的性质。在插入元素时,使用upHeap方法调整数组元素的位置,以维护最大堆的性质;在删除元素时,使用downHeap方法调整数组元素的位置,以维护最大堆的性质。在需要获取队列中的最大元素时,始终返回数组的第一个元素即可。

1.堆的概念

如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储 在一
个一维数组中,并满足:Ki <= K2i+1 且 Ki<= K2i+2 (Ki >= K2i+1 且 Ki >= K2i+2) i = 0,1,2…,则称为 小堆(或大
堆)。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。


2.堆的性质

1.堆中某个节点的值总是不大于或不小于其父节点的值;

2.堆总是一棵完全二叉树。

3.堆的存储方式

从堆的概念可知,堆是一棵完全二叉树,因此可以层序的规则采用顺序的方式来高效存储,


注意:对于非完全二叉树,则不适合使用顺序方式进行存储,因为为了能够还原二叉树,空间中必须要存储空节点,就会导致空间利用率比较低。
       

      将元素存储到数组中后,可以对树进行还原。

  • 假设i为节点在数组中的下标,则有:
  • 如果i为0,则i表示的节点为根节点,否则i节点的双亲节点为 (i - 1)/2
  • 如果2 * i + 1 小于节点个数,则节点i的左孩子下标为2 * i + 1,否则没有左孩子
  • 如果2 * i + 2 小于节点个数,则节点i的右孩子下标为2 * i + 2,否则没有右孩子

4.堆的创建

问题:对于集合{ 0,1,2,3,5,68 }中的数据,如果将其创建成最大堆呢?

1.如何把给定的一棵二叉树,变成最小堆或者最大堆

以变成最大堆为例

从这棵树的最后一棵子树开始调整,从右往左,从上往下 
仔细观察上图后发现:根节点的左右子树已经完全满足堆的性质,因此只需将根节点向下调整好即可。

向下过程(以最大堆为例):
1. 让parent标记需要调整的节点,child标记parent的左孩子(注意:parent如果有孩子一定先是有左孩子)
2. 如果parent的左孩子存在,即:child > size, 进行以下操作,直到parent的左孩子不存在
        parent右孩子是否存在,存在找到左右孩子中较大的孩子,让child进行标计,
        将parent与较大的孩子child比较,

                如果:parent大于较大的孩子child,调整结束
                否则:交换parent与较大的孩子child,交换完成之后,parent中大的元素向下移动,可能导致子树不满足最大堆的性质,

                因此需要继续向下调整,即parent = child;child = parent*2+1; 然后继续。

public class MaxHeapify {
    private int[] heap; // 存储二叉树节点的数组
    private int size; // 二叉树的大小

    public MaxHeapify(int n) {
        heap = new int[n + 1]; // 创建一个大小为 n+1 的数组,因为数组下标从0开始
        size = 0; // 二叉树的大小初始为0
    }

    public void add(int val) {
        heap[++size] = val; // 将新节点插入到数组的末尾
        int i = size; // 当前节点下标
        while (i > 1 && heap[i / 2] < heap[i]) { // 如果当前节点不是根节点且当前节点的值大于根节点的值
            swap(i, i / 2); // 则交换当前节点和根节点
            i /= 2; // 重新获取当前节点下标
        }
    }

    public int get(int i) {
        return heap[i]; // 返回指定下标的节点的值
    }

    public void maxHeapify(int i) { // i表示当前节点的下标
        int left = 2 * i + 1; // 左子节点的下标
        int right = 2 * i + 2; // 右子节点的下标
        int largest = i; // 记录最大的节点下标
        if (left < size && heap[left] > heap[largest]) { // 如果左子节点存在且值大于当前最大值
            largest = left; // 更新最大值下标为左子节点下标
        }
        if (right < size && heap[right] > heap[largest]) { // 如果右子节点存在且值大于当前最大值
            largest = right; // 更新最大值下标为右子节点下标
        }
        if (largest != i) { // 如果当前节点不是最大值节点
            swap(i, largest); // 则交换当前节点和最大值节点
            maxHeapify(largest); // 对新的当前节点进行最大堆调整
        }
    }

    private void swap(int i, int j) { // i和j分别表示两个节点的下标
        int temp = heap[i]; // 保存第一个节点的值
        heap[i] = heap[j]; // 将第二个节点的值赋给第一个节点
        heap[j] = temp; // 将第一个节点的值赋给第二个节点
    }
}

/*注释:
private int[] heap; 和 private int size; 分别表示存储二叉树节点的数组和二叉树的大小。
public MaxHeapify(int n) 是构造函数,创建一个大小为 n+1 的数组,因为数组下标从0开始。
public void add(int val) 方法将新节点插入到数组的末尾,然后通过交换节点和其父节点来调整二叉树,使其满足最大堆的性质。
public int get(int i) 方法返回指定下标的节点的值。
public void maxHeapify(int i) 方法用于调整以 i 为根节点的子树为最大堆。首先找到左右子节点中最大的节点,然后与当前节点进行交换,并对新的当前节点进行最大堆调整。这个方法使用了递归的方式,直到每个子树都是最大堆为止。
private void swap(int i, int j) 方法用于交换两个节点的值。*/
    public void shiftDown(int[] array, int parent) {
        // child先标记parent的左孩子,因为parent可能右左没有右
        int child = 2 * parent + 1;
        int size = array.length;
        while (child < size) {
            // 如果右孩子存在,找到左右孩子中较小的孩子,用child进行标记
            if (child + 1 < size && array[child + 1] < array[child]) {
                {
                    child += 1;
                }
            }
            // 如果双亲比其最小的孩子还小,说明该结构已经满足堆的特性了
            if (array[parent] <= array[child]) {
                break;
            } else {
            // 将双亲与较小的孩子交换
                int t = array[parent];
                array[parent] = array[child];
                array[child] = t;
            // parent中大的元素往下移动,可能会造成子树不满足堆的性质,因此需要继续向下调整
                parent = child;
                child = parent * 2 + 1;
            }
        }
    }

注意:在调整以parent为根的二叉树时,必须要满足parent的左子树和右子树已经是堆了才可以向下调整。

2.时间复杂度分析

时间复杂度分析:最坏的情况即图示的情况,从根一路比较到叶子,比较的次数为完全二叉树的高度,即时间复杂度为O(log2n)

建堆的时间复杂度


因为堆是完全二叉树,而满二叉树也是完全二叉树,此处为了简化使用满二叉树来证明(时间复杂度本来看的就是
近似值,多几个节点不影响最终结果):

因此:建堆的时间复杂度为O(N)。
堆的插入与删除
2.4.1 堆的插入
堆的插入总共需要两个步骤:
1. 先将元素放入到底层空间中(注意:空间不够时需要扩容)
2. 将最后新插入的节点向上调整,直到满足堆的性质

public void shiftUp(int child) {
    // 找到child的双亲
    int parent = (child - 1) / 2;
    while (child > 0) {
    // 如果双亲比孩子大,parent满足堆的性质,调整结束
       if (array[parent] > array[child]) {
           break;
        } else {
    // 将双亲与孩子节点进行交换
           int t = array[parent];
           array[parent] = array[child];
           array[child] = t;
    // 小的元素向下移动,可能到值子树不满足对的性质,因此需要继续向上调增
           child = parent;
           parent = (child - 1) / 1;
        }
    }
}

 5.堆的删除

 注意:堆的删除一定删除的是堆顶元素。具体如下:
1. 将堆顶元素对堆中最后一个元素交换
2. 将堆中有效数据个数减少一个
3. 对堆顶元素进行向下调整

 6.用堆模拟实现优先级队列

public class MyPriorityQueue {
    // 演示作用,不再考虑扩容部分的代码
    private int[] array = new int[100];
    private int size = 0;

    public void offer(int e) {
        array[size++] = e;
        shiftUp(size - 1);
    }

    public int poll() {
        int oldValue = array[0];
        array[0] = array[--size];
        shiftDown(0);
        return oldValue;
    }

    public int peek() {
        return array[0];
    }
}

7.常用接口介绍

PriorityQueue的特性:Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,主要介绍的是PriorityQueue。

1.关于PriorityQueue的使用注意事项

关于PriorityQueue的使用要注意:
1. 使用时必须导入PriorityQueue所在的包,即:
import java.util.PriorityQueue;
2. PriorityQueue中放置的元素必须要能够比较大小,不能插入无法比较大小的对象,否则会抛出
ClassCastException异常
3. 不能插入null对象,否则会抛出NullPointerException
4. 没有容量限制,可以插入任意多个元素,其内部可以自动扩容
5. 插入和删除元素的时间复杂度为
6. PriorityQueue底层使用了堆数据结构
7. PriorityQueue默认情况下是小堆---即每次获取到的元素都是最小的元素
3.2 PriorityQueue常用接口介绍


1. 优先级队列的构造

PriorityQueue中常见的几种构造方式

    public static void TestPriorityQueue() {
        // 创建一个空的优先级队列,底层默认容量是11
        PriorityQueue<Integer> q1 = new PriorityQueue<>();
        // 创建一个空的优先级队列,底层的容量为initialCapacity
        PriorityQueue<Integer> q2 = new PriorityQueue<>(100);
        ArrayList<Integer> list = new ArrayList<>();
        list.add(4);
        list.add(3);
        list.add(2);
        list.add(1);
        // 用ArrayList对象来构造一个优先级队列的对象
        // q3中已经包含了三个元素
        PriorityQueue<Integer> q3 = new PriorityQueue<>(list);
        System.out.println(q3.size());
        System.out.println(q3.peek());
    }

 注意:默认情况下,PriorityQueue队列是小堆,如果需要大堆需要用户提供比较器

public class TestPriorityQueue {
    public static void main(String[] args) {
        PriorityQueue<Integer> p = new PriorityQueue<>(new IntCmp());
        p.offer(4);
        p.offer(3);
        p.offer(2);
        p.offer(1);
        p.offer(5);
        System.out.println(p.peek());
    }
}

此时创建出来的就是一个大堆。

2. 插入/删除/获取优先级最高的元素                                           

函数名 功能介绍
boolean offer(E e) 插入元素e,插入成功返回true,如果e对象为空,抛出NullPointerException异常,时间复杂度O(log2N),注意:空间不够时候会进行扩容
E peek() 获取优先级最高的元素,如果优先级队列为空,返回null
E poll() 移除优先级最高的元素并返回,如果优先级队列为空,返回null
int size() 获取有效元素的个
void clear() 清空
boolean isEmpty() 检测优先级队列是否为空,空返回true

 public static void TestPriorityQueue2() {
        int[] arr = {4, 1, 9, 2, 8, 0, 7, 3, 6, 5};
        // 一般在创建优先级队列对象时,如果知道元素个数,建议就直接将底层容量给好
        // 否则在插入时需要不多的扩容
        // 扩容机制:开辟更大的空间,拷贝元素,这样效率会比较低
        PriorityQueue<Integer> q = new PriorityQueue<>(arr.length);
        for (int e : arr) {
            q.offer(e);
        }
        System.out.println(q.size()); // 打印优先级队列中有效元素个数
        System.out.println(q.peek()); // 获取优先级最高的元素
        // 从优先级队列中删除两个元素之和,再次获取优先级最高的元素
        q.poll();
        q.poll();
        System.out.println(q.size()); // 打印优先级队列中有效元素个数
        System.out.println(q.peek()); // 获取优先级最高的元素
        q.offer(0);
        System.out.println(q.peek()); // 获取优先级最高的元素
        // 将优先级队列中的有效元素删除掉,检测其是否为空
        q.clear();
        if (q.isEmpty()) {
            System.out.println("优先级队列已经为空!!!");
        } else {
            System.out.println("优先级队列不为空");
        }
    }

注意:以下是JDK 1.8中,PriorityQueue的扩容方式:

    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    private void grow(int minCapacity) {
        int oldCapacity = queue.length;
        // Double size if small; else grow by 50%
        int newCapacity = oldCapacity + ((oldCapacity < 64) ?
                (oldCapacity + 2) :
                (oldCapacity >> 1));
        // overflow-conscious code
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        queue = Arrays.copyOf(queue, newCapacity);
    }
    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
    }

优先级队列的扩容说明:
如果容量小于64时,是按照oldCapacity的2倍方式扩容的
如果容量大于等于64,是按照oldCapacity的1.5倍方式扩容的
如果容量超过MAX_ARRAY_SIZE,按照MAX_ARRAY_SIZE来进行扩容

完结撒花✿✿ヽ(°▽°)ノ✿


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一万字关于java数据结构堆的讲解,让你从入门到精通 的相关文章

  • Java 中等效的并行扩展

    我在 Net 开发中使用并行扩展有一些经验 但我正在考虑在 Java 中做一些工作 这些工作将受益于易于使用的并行库 JVM 是否提供任何与并行扩展类似的工具 您应该熟悉java util concurrent http java sun
  • 在 Java 中连接和使用 Cassandra

    我已经阅读了一些关于 Cassandra 是什么以及它可以做什么的教程 但我的问题是如何在 Java 中与 Cassandra 交互 教程会很好 如果可能的话 有人可以告诉我是否应该使用 Thrift 还是 Hector 哪一个更好以及为什
  • 如何为最终用户方便地启动Java GUI程序

    用户想要从以下位置启动 Java GUI 应用程序Windows 以及一些额外的 JVM 参数 例如 javaw Djava util logging config file logging properties jar MyGUI jar
  • Java Swing:从 JOptionPane 获取文本值

    我想创建一个用于 POS 系统的新窗口 用户输入的是客户拥有的金额 并且窗口必须显示兑换金额 我是新来的JOptionPane功能 我一直在使用JAVAFX并且它是不同的 这是我的代码 public static void main Str
  • 如何在 Play java 中创建数据库线程池并使用该池进行数据库查询

    我目前正在使用 play java 并使用默认线程池进行数据库查询 但了解使用数据库线程池进行数据库查询可以使我的系统更加高效 目前我的代码是 import play libs Akka import scala concurrent Ex
  • Java JDBC:更改表

    我希望对此表进行以下修改 添加 状态列 varchar 20 日期列 时间戳 我不确定该怎么做 String createTable Create table aircraft aircraftNumber int airLineCompa
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • Android:捕获的图像未显示在图库中(媒体扫描仪意图不起作用)

    我遇到以下问题 我正在开发一个应用程序 用户可以在其中拍照 附加到帖子中 并将图片保存到外部存储中 我希望这张照片也显示在图片库中 并且我正在使用媒体扫描仪意图 但它似乎不起作用 我在编写代码时遵循官方的Android开发人员指南 所以我不
  • 多个 Maven 配置文件激活多个 Spring 配置文件

    我想在 Maven 中构建一个环境 在其中我想根据哪些 Maven 配置文件处于活动状态来累积激活多个 spring 配置文件 目前我的 pom xml 的相关部分如下所示
  • 加速代码 - 3D 数组

    我正在尝试提高我编写的一些代码的速度 我想知道从 3d 整数数组访问数据的效率如何 我有一个数组 int cube new int 10 10 10 我用价值观填充其中 然后我访问这些值数千次 我想知道 由于理论上所有 3d 数组都存储在内
  • 反射找不到对象子类型

    我试图通过使用反射来获取包中的所有类 当我使用具体类的代码 本例中为 A 时 它可以工作并打印子类信息 B 扩展 A 因此它打印 B 信息 但是当我将它与对象类一起使用时 它不起作用 我该如何修复它 这段代码的工作原理 Reflection
  • Mockito when().thenReturn 不必要地调用该方法

    我正在研究继承的代码 我编写了一个应该捕获 NullPointerException 的测试 因为它试图从 null 对象调用方法 Test expected NullPointerException class public void c
  • 无法解析插件 Java Spring

    我正在使用 IntelliJ IDEA 并且我尝试通过 maven 安装依赖项 但它给了我这些错误 Cannot resolve plugin org apache maven plugins maven clean plugin 3 0
  • 斯坦福 NLP - 处理文件列表时 OpenIE 内存不足

    我正在尝试使用斯坦福 CoreNLP 中的 OpenIE 工具从多个文件中提取信息 当多个文件 而不是一个 传递到输入时 它会给出内存不足错误 All files have been queued awaiting termination
  • 如何将 pfx 文件转换为 jks,然后通过使用 wsdl 生成的类来使用它来签署传出的肥皂请求

    我正在寻找一个代码示例 该示例演示如何使用 PFX 证书通过 SSL 访问安全 Web 服务 我有证书及其密码 我首先使用下面提到的命令创建一个 KeyStore 实例 keytool importkeystore destkeystore
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • 捕获的图像分辨率太大

    我在做什么 我允许用户捕获图像 将其存储到 SD 卡中并上传到服务器 但捕获图像的分辨率为宽度 4608 像素和高度 2592 像素 现在我想要什么 如何在不影响质量的情况下获得小分辨率图像 例如我可以获取或设置捕获的图像分辨率为原始图像分
  • 使用 JMF 创建 RTP 流时出现问题

    我正处于一个项目的早期阶段 需要使用 RTP 广播DataStream创建自MediaLocation 我正在遵循一些示例代码 该代码目前在rptManager initalize localAddress 出现错误 无法打开本地数据端口
  • java.lang.IllegalStateException:驱动程序可执行文件的路径必须由 webdriver.chrome.driver 系统属性设置 - Similiar 不回答

    尝试学习 Selenium 我打开了类似的问题 但似乎没有任何帮助 我的代码 package seleniumPractice import org openqa selenium WebDriver import org openqa s
  • 按日期对 RecyclerView 进行排序

    我正在尝试按日期对 RecyclerView 进行排序 但我尝试了太多的事情 我不知道现在该尝试什么 问题就出在这条线上适配器 notifyDataSetChanged 因为如果我不放 不会显示错误 但也不会更新 recyclerview

随机推荐

  • 解决Android Studio编译报错:找不到NotNull或Nullable

    问题 在java代码中引入 import org jetbrains annotations NotNull import org jetbrains annotations Nullable 导致代码编译不过 找不到这两个类库 按照官方文
  • 后端学习React的第一天

    java后端了十几年了 曾经在学校写过一些jquery的前端代码 后来前端的框架越来越复杂 加上工作以后都是前后端分离的 并且自己美术功底本来也就不咋地 逐渐就放弃了前端技术 专职后端开发了 最近闲来无事 想写点有意思的小程序 发现没有前端
  • 教你如何用fiddler抓取https(详细教程)

    对于想抓取HTTPS的测试初学者来说 常用的工具就是fiddler 可是在初学时 大家对于fiddler如何抓取HTTPS真是伤了脑筋 可能你一步步按着网上的帖子成功了 那当然是极好的 有可能没有成功 这时候你就很抓狂了 我把网络上的教程进
  • python实现文件(夹)剪切

    自己的需求是这样的 有a和b两个目录 a目录下的文件 夹 要剪切到b目录下 我用下面这种形式来表达需求 不然说得比较乱 需求如下 a目录 1 文件 1 是日志文件 1 文件大小 lt 20m 跳过 2 日志文件 gt 20m 复制名加上当天
  • ssh连接不上Linux怎么办

    原因 被防火墙挡掉 ssh服务配置文件中的参数是否拒绝了连接等等 解决方法 一 开启SSH 以root用户登录Linux 打开终端 运行 etc init d sshd restrat 二 关闭防火墙 1 在终端运行 setup 2 选择
  • es6 处理数组的方法汇总

    目录 创建数组静态方法 ES6 Array from Array of 检测数组方法 instanceof Array isArray 迭代器方法 ES6 keys values entries 复制和填充方法 ES6 Array fill
  • 逻辑回归输出的值是真实的概率吗?

    本文只在博客基础上 在三 指数分布族中有所改动 逻辑回归作为被广泛使用的二分类模型 面试中自然是不可缺少的 但要深刻理解逻辑回归又不是那么容易的 比如说 逻辑回归输出的值是0到1之间的值 这个值是真实的概率吗 逻辑回归为什么要选择sigmo
  • layui树形美化_Layui导航树美化 - walkwithdream的个人空间 - OSCHINA - 中文开源技术交流社区...

    左侧导航 使用方法 skin sidebar layui tree skin sidebar li i color rgba 255 255 255 7 display none layui tree skin sidebar li a c
  • 学习Java——为什么java只有值传递

    目录 Java的求值策略 Java中的对象传递 值传递和共享对象传递冲突吗 总结 参考资料 Java的求值策略 前面我们介绍过了传值调用 传引用调用以及传值调用的特例传共享对象调用 那么 Java中是采用的哪种求值策略呢 很多人说Java中
  • 最优乘车问题/dijsktra最短路径算法

    城是一个旅游胜地 每年都有成千上万的人前来观光 为方便游客 巴士公司在各个旅游景点及宾馆 饭店等地都设置了巴士站 并开通了一些单向巴士线路 每条单向巴士线路从某个巴士站出发 依次途径若干个巴士站 最终到达终点巴士站 阿昌最近到 城旅游 住在
  • typora笔记工具使用详解

    Markdown使用笔记 首先本地使用安装教程 百度搜索typora第一个就是官网 地址为 typora下载地址 下载步骤如下 简单使用教程 3 Markdown标题 使用 号可表示 1 6 级标题 一级标题对应一个 号 二级标题对应两个
  • 读取.ini文件乱码的解决办法

    void CGetConfigInfo GetValueByKey QSettings seting const QString key QString value if seting nullptr value seting gt val
  • Memory write error at 0x100000. MMU section translation fault

    在使用vitis2020 2 JTAG调试MZ702P板子的时候会报下面的错误 原因都是启动模式没有设置到JTAG启动或SD启动 记得之前用SDK的时候好像没有这个问题 记录一下 备忘 Downloading Program F FPGA
  • ONVIF对讲功能漫谈

    ONVIF对讲功能漫谈 前言 一 onvif对讲功能和onvif协议关系大吗 二 如何上报设备支持onvif对讲功能呢 三 onvif协议中哪个接口上报音频解码配置 四 献上抓包报文 前言 本篇文章尝试使用提问的方式来分享onvif对讲功能
  • java类型信息与反射

    初步理解 https www cnblogs com xuanlin666 p 10826809 html
  • 使用Electron开发过程中不能使用remote模块解决

    在 electron 渲染进程中引入BrowserWindow报错 const BrowserWindow require electron remote BrowserWindow 报错 Cannot read properties of
  • c++ADO编程-connection对象

    Connection对象的属性有如下几个 1 ConnectionString属性 是连接字符串 通过传递包含一系列由分号分隔的 argument value 语句的详细连接字符串 可指定用于建立连接数据源的信息 连接串格式根据数据源的不同
  • 3.2面向对象

    面向对象与面向过程的区别 面向过程指的是工作过程如何执行 而面向对象指的是工作该让谁来完成 面向对象三大思想 OOA 面向对象分析 Object Oriented Analysis OOD 面向对象设计 Object Oriented De
  • 剑指 Offer 15. 二进制中1的个数(java+python)

    编写一个函数 输入是一个无符号整数 以二进制串的形式 返回其二进制表达式中数字位数为 1 的个数 也被称为 汉明重量 提示 请注意 在某些语言 如 Java 中 没有无符号整数类型 在这种情况下 输入和输出都将被指定为有符号整数类型 并且不
  • 一万字关于java数据结构堆的讲解,让你从入门到精通

    目录 java类和接口总览 队列 Queue 1 概念 2 队列的使用 以下是一些常用的队列操作 1 入队操作 2 出队操作 3 判断队列是否为空 4 获取队列大小 5 其它 优先级队列 堆 1 优先级队列概念 Java中的Priority