详解Java中的Collection单列集合(从底层到用法超详细解析和细节分析)

⭕在 Java 中,集合框架是开发过程中最常用的数据结构之一,其中 Collection 接口是整个集合框架的基础。Collection 是处理单列数据的接口,它定义了一些通用的操作,允许对一组对象进行操作。今天我们将深入介绍 Java 中的单列集合 Collection 接口,以及它的常见子接口和实现类。

在谈论集合时,我们都有一个问题,那就是数组和集合有什么区别?

相同点

  • 集合和数组都是容器,可以用来存储多个数据

不同点

  • 数组长度是不可变的,集合的长度是可以变的

  • 集合只能存储引用数据类型,如果要存储基本数据类型,需要存对应的包装类

  • 集合中集成了很多实用的数据处理方法,提供了功能各异的集合以达到提高程序运行效率的目的

想要深入了解Collection集合,我们就得先了解其在整个集合类的体系结构中的位置


一、集合体系结构图(Collection在集合体系中的位置)


二、创建Colletion对象的方式

由集合体系结构图可知Collection类是单列集合的顶层接口,所以不能通过它直接创建对象,我们需要用到其子接口的实现类或者通过多态的方式创建其对象。

2.1 多态的方式

2.2 具体实现类


三、Collection 核心(常用)方法

方法名称返回类型描述
boolean add(E e)boolean向集合中添加元素。如果集合因为此调用发生了变化,则返回 true
boolean remove(Object o)boolean从集合中删除指定元素。如果集合包含该元素并成功移除,则返回 true
boolean contains(Object o)boolean判断集合中是否包含指定的元素。如果集合包含此元素,则返回 true
int size()int返回集合中元素的数量。
Iterator<E> iterator()Iterator<E>返回一个用于遍历集合中元素的迭代器。
void clear()void清空集合中的所有元素。
boolean isEmpty()boolean判断集合是否为空。如果集合为空,则返回 true

3.1 add方法

向集合中添加元素。如果集合因为此调用发生了变化,则返回 true

细节:

  • 如果往List系列集合中添加元素永远返回true,因为List系列集合元素可重复
  • 如果往List系列集合中添加元素如果元素已经存在,则会返回false

3.2 remove方法

从集合中删除指定元素。如果集合包含该元素并成功移除,则返回 true,如果元素不存在则返回false

细节:因为Collection里面定义的是共性的方法(Set系列集合也要适用),所以此时不能通过索引进行删除,这里面具体涉及多态中方法重写和重载的区别,可以参考我另外一篇文章

在多态的方法调用中为什么会出现“左边编译左边运行”的现象icon-default.png?t=O83Ahttps://blog.csdn.net/q251932440/article/details/142509834?spm=1001.2014.3001.5501

3.3 clear方法

清空集合中的所有元素。

3.4 contains方法

细节:contains方法依赖equals方法进行判断,所以如果集合中存储自定义对象时,需要在JavaBean类中重写equals方法。

Student中重写的equals方法:

3.5 size方法

返回集合中元素的数量。

3.6 isEmpty方法

判断集合是否为空。如果集合为空,则返回 true

3.7 iterator方法

返回一个用于遍历集合中元素的迭代器。(在下文迭代器中介绍)


四、Collection集合的遍历

Collection集合中通用的遍历方法有三种(均不依赖索引):

  • 迭代器遍历
  • 增强for遍历
  • Lambda表达式遍历

4.1 迭代器遍历

迭代器:是集合专门用来遍历的工具。

在源码中可以看到,迭代器Iterator是一个接口类,所以不能直接创建其对象来使用,需要通过集合对象中的iterator()方法返回一个Iterator接口实现类的对象

1. 接口无法直接创建对象

接口无法直接实例化是因为它没有实现方法的具体细节。接口只是一个契约,定义了类必须实现的方法。比如,Iterator 接口定义了 hasNext()next()remove() 方法,但并没有提供这些方法的具体实现。

2. ArrayListiterator() 方法

当你调用 ArrayListiterator() 方法时,它内部实际上是返回了一个 匿名内部类具体的类 的实例,这个实例实现了 Iterator 接口。也就是说,虽然我们只看到了 Iterator 接口,但它实际是 ArrayList 内部某个私有类的对象,该类实现了 Iterator 接口的所有方法。

ArrayList 源代码中,iterator() 方法大概像这样实现:

public Iterator<E> iterator() {return new Itr();  // 返回一个实现了 Iterator 接口的类的实例
}private class Itr implements Iterator<E> {// 实现 Iterator 接口的方法,如 hasNext(), next(), remove()public boolean hasNext() {// 具体实现}public E next() {// 具体实现}public void remove() {// 具体实现}
}

4.1.1 迭代器(Iterator)常用方法表格

方法名称返回类型描述
boolean hasNext()boolean判断集合中是否还有下一个元素。如果有,返回 true;否则返回 false。通常用于循环控制。
E next()E返回集合中的下一个元素,并将迭代器的指针移动到下一个元素。如果已经没有元素可返回,调用该方法会抛出 NoSuchElementException 异常。
void remove()void移除迭代器当前指向的元素(即最近一次调用 next() 方法返回的元素)。这是可选操作,如果集合不支持 remove() 方法,调用时会抛出异常。

4.1.2 示例1-遍历:

细节:迭代遍历结束后,指针不会复位,如果还想遍历则要新建一个迭代器

4.1.3 示例2-遍历的过程中删除元素

移除迭代器当前指向的元素(即最近一次调用 next() 方法返回的元素

如果要删除,用迭代器的remove方法,如果用集合的方法进行增加或者删除会报错

正确用法:

4.1.4 迭代器使用的注意点

  • 迭代器遍历完毕后,指针不会复位,如果还要继续遍历,需要新建一个迭代器
  • 指针处已经没有元素仍要执行next方法,系统会报错 'NoSuchElementException' (空元素异常)
  • 循环中,只能使用一次next方法,如果在一个循环中多次调用next方法,元素总数为奇数的时候也会有 'NoSuchElementException' (空元素异常)报错的风险
  • 迭代遍历的过程中(循环里)不能用集合的方法进行增删改查
  • 数组不能直接使用迭代器进行遍历,需要使用需转换为集合

4.2 增强for遍历

  • 增强for于JDK5后问世,其内部原理是一个Iterator迭代器
  • 所有单列集合和数组才能使用增强for进行遍历

作用:简化数组和集合的遍历,增加安全性

格式:

for(集合/数组中元素的数据类型 变量名 : 集合/数组名) {// 已经将当前遍历到的元素封装到变量中了,直接使用变量即可}

快捷:集合/数组.for 回车——自动生成增强for代码块

4.2.1 示例:

4.2.2 增强for注意点

增强for里面的Student student是一个第三方变量,student是其变量名,改变该变量值,不会影响集合中的数据

验证:

4.3 Lambda表达式遍历

利用forEach方法,结合Lambda表达式进行遍历(其底层是增强for)

作用:简化代码

4.3.1 示例:

使用forEach后,使用Lambda表达式前:

使用Lambda表达式后:

4.3.2 使用剖析 

通过查看源码可以知道,forEach方法需要传入的形参是一个Consumer接口类型的数据,而且是一个函数式接口。所以我们在传入参数的时候需要传入一个Consumer接口的实现类对象,因此采用了匿名内部类的方式创建其实现类对象并传入到方法中,然后根据Lambda表达式格式改写成Lambda表达式以简化代码。

4.3.3 注意:

修改student一样不会改变集合的值,和增强for一样(因为底层就是一个增强for)

4.4 三种遍历方法的使用场景


五、Collection子接口——List集合

5.1 List集合的特点

  • 存取有序(指的是存和取得顺序一样,跟排序不同
  • 可以重复
  • 有索引

List继承了Collection,但List仍然是一个接口类,如果想要创建List集合,则需要创建List接口得实现类对象 (ArrayList、LinkedList),例如:

5.2 List集合的特有方法

  • List继承了Collection,拥有Collection集合的所有方法
  • 因为List集合支持索引,索引新增了一些处理索引的方法方法介绍

方法列表:

方法名描述
void add(int index,E element)在此集合中的指定位置插入指定的元素
E remove(int index)删除指定索引处的元素,返回被删除的元素
E set(int index,E element)修改指定索引处的元素,返回被修改的元素
E get(int index)返回指定索引处的元素

5.2.1 add方法

在List集合中有两种add方法:

  • Collection中的add
  • void add(int index,E element)  在此集合中的指定位置插入指定的元素

这里重点分析第二种

代码示例:

打印结果:

由上述代码可知,使用add指定添加索引后,原本在该索引的元素会往后退一位让出索引,其后面的元素都会依次往后移动

5.2.2 remove方法

List集合中remove方法也有两种:

  • Collection中的remove
  • E remove(int index)  删除指定索引处的元素,返回被删除的元素

这里仍然重点分析第二种

代码示例:

标识代码块中的打印结果:

由上述代码可知,当使用remove删除一个元素的时候,被删除所在元素的位置就会空了,其后面的元素会自动依次向前移动

细节问题

当创建一个整数类型的集合时,采用remove方法删除会使用删除索引的remove方法还是使用删除元素的remove方法?

代码演示:

如果一定要使用其删除1这个元素,就需要进行手动装箱:

5.2.3 set方法

5.2.4 get方法

5.3 List集合遍历方式及对比

5.3.1 迭代器遍历

5.3.2 列表迭代器

往前迭代那个方法有局限性,因为迭代器一开始默认实在0索引处的(基本不用)

遍历过程中添加元素:

5.3.3 增强for

5.3.4 Lambda表达式

5.3.5 普通for循环

5.4 List的实现类——LinkedList

5.4.1 底层核心步骤

  1. 刚开始创建的时候,底层创建了两个变量:一个记录头结点first,一个记录尾结点last,默认为null

  2. 添加第一个元素时,底层创建一个结点对象,first和last都记录这个结点的地址值

  3. 添加第二个元素时,底层创建一个结点对象,第一个结点会记录第二个结点的地址值,last会记录新结点的地址值

LinkedList集合底层是链表结构实现的,查询慢,增删快

5.4.2 特有方法

但是如果操作首尾元素,速度也是非常快的,所以LinkedList多了一些操作首尾元素的方法:

方法名说明
public void addFirst(E e)在该列表开头插入指定的元素
public void addLast(E e)将指定的元素追加到此列表的末尾
public E getFirst()返回此列表中的第一个元素
public E getLast()返回此列表中的最后一个元素
public E removeFirst()从此列表中删除并返回第一个元素
public E removeLast()从此列表中删除并返回最后一个元素

但是这些方法用得比较少,在Collection和List的方法中也基本能实现。

5.5 List的实现类——ArrayList

5.5.1 底层核心步骤:

  • 创建ArrayList对象的时候,他在底层先创建了一个长度为0的数组。
    • 数组名字:elementDate,定义变量size。
  • size这个变量有两层含义(添加元素,添加完毕后,size++):
    • ①:元素的个数,也就是集合的长度
    • ②:下一个元素的存入位置

当添加第一个元素的时候,底层会创建一个新的长度为10的数组

  • 扩容时机一:
    • 当存满时候,会创建一个新的数组,新数组的长度,是原来的1.5倍,也就是长度为15.再把所有的元素,全拷贝到新数组中。
    • 如果继续添加数据,这个长度为15的数组也满了,那么下次还会继续扩容,还是1.5倍。
  • 扩容时机二:
    • 如果一次添加多个元素,1.5倍放不下,那么新创建数组的长度以实际为准。

六、Collection子接口——Set集合

Set中的方法基本和Collection中的方法一致

6.1 Set集合的特点

  • 数据存取顺序不一致(LinkedHashSet除外)
  • 不可存储重复元素(可以利用这个特点来对数据去重)
    • add方法的返回值在Set中奏效了,如果重复的元素添加进集合,会添加失败并返回false
  • 没有索引(遍历时不能使用普通for)

6.1.1 Set实现类与子实现类的特点

6.2 Set集合遍历方式

与Collection一样:

  • 迭代器
  • 增强for
  • Lambda表达式

6.2.1 迭代器遍历

6.2.2 增强for

6.2.3 Lambda表达式

6.3 Set的实现类——HashSet

6.3.1 特点

  • 底层数据结构是哈希表(JDK8以后由数组+链表+红黑树组成) 
    • 默认加载因子:填充的元素达到数组长度的75%就扩容一倍
  • 存取无序
  • 不可以存储重复元素
  • 没有索引 
  • 增删改查的性能都很好

6.3.2 哈希值

JDK根据对象的地址或者字符串或者数字算出来的int类型的数值

⭕哈希值的获取

Object类中的public int hashCode():返回对象的哈希值

⭕哈希值的特点
  • 同一个对象多次调用hashCode()方法返回的哈希值是相同的

  • 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象而属性值相同的哈希值相同String等java已经定义好的对象已经重写了该方法

  • 在小部分情况下,不同属性值或者不同地址值计算出来的哈希值也有可能一样(哈希碰撞)

    • 因此为了避免哈希碰撞导致部分元素丢失,通常也要重写自定义对象(String等java已经定义好的对象已经重写了该方法)中的equals方法

      • 原因:这样一来,即使哈希值相同的元素还会被进一步被equals方法确认是否为重复元素,放防止直接被丢掉不存。

6.3.3 代码示例

学生类:
package test01;import java.util.Objects;public class Student {private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return age*/public int getAge() {return age;}/*** 设置* @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "Student{name = " + name + ", age = " + age + "}";}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, age);}
}
测试类:
package test01;import java.util.HashSet;
import java.util.Set;public class SetTest01 {public static void main(String[] args) {Set<Student> set1 = new HashSet<>();Student s1 = new Student("zhangsan",11);Student s2 = new Student("lisi",13);Student s3 = new Student("wangwu",12);set1.add(s1);set1.add(s2);set1.add(s3);set1.forEach(student -> System.out.println(student));}
}

6.3.4 HashSet子类——LinkedHashSet

LinkedHashSet与HashSet不同的是:LinkedHashSet集合存取元素是有序的

为什么存取有序?

LinkedHashSet其底层数据结构依然是哈希表,只是每个元素又额外增加了一个双链表机制记录存储的顺序。

通过以下代码展示,我们可以知道LinkedHashSet集合存取元素是有序的

如果以后数据要去重,我们使用哪一个集合?

6.4 Set的实现类——TreeSet

6.4.1 特点

  • 可以将元素按照规则排序(以下必选其一,不然获取集合会报错)
    • 实现Comparable接口进行自然排序
    • 使用比较排序器Comparator
  • 不可存储重复元素(依赖上述两种比较方法实现的,因此不需要类重写HashCode和equals方法
  • 没有索引
  • 底层数据结构为红黑树

6.4.2 在没有排序时的TreeSet集合:

当我们添加自定义对象进集合后,TreeSet不知道排序规则,会出现如下报错(类转换异常

如果我们添加整数类型的对象进TreeSet中,会得到以下结果,其数据从小到大排列起来了

那为什么会出现这种状况呢?TreeSet的排序规则是什么呢?

6.4.3 TreeSet的默认排序规则

TreeSet的排序都是要实现Comparable接口进行自然排序或者使用比较排序器Comparator来进行的,之所以java中的一些定义好的数据类如Integer、String等能够直接排序(有默认排序规则)是因为java已经在这些类上实现了Comparable接口。

Integer源码

  • 对于数值类型(如Integer、Double):默认按照从小到大顺序进行排序
  • 对于字符、字符串类型:按照字符在ASCII码表中的数字升序进行排序(从小到大)
    • 剖析字符串排序:
  • 自定义对象,需要实现Comparable接口进行自然排序或者使用比较排序器Comparator

那么接下来我们就开始介绍这两种排序方法。

6.4.4 TreeSet的排序方法

⭕自然排序Comparable接口的使用 
实现步骤
  1. 使用空参构造创建TreeSet集合

    用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
  2. 自定义的Student类实现Comparable接口

    自然排序,就是让元素所属的类实现Comparable接口,指定要对比的类型,重写compareTo(T o)方法
  3. 重写接口中的compareTo方法(指定排序规则

    重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
代码示例:
  • 存储学生对象并遍历,创建TreeSet集合使用无参构造方法

  • 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序

学生类:

package test01;import java.util.Objects;public class Student implements Comparable<Student>{private String name;private int age;public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return age*/public int getAge() {return age;}/*** 设置* @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "Student{name = " + name + ", age = " + age + "}";}@Overridepublic int compareTo(Student o) {//大于0说明this.age大,排在后面int result = this.age - o.age;//this.name.compareTo(o.name),因为this.name是一个字符串对象//调用字符串对象可以用到字符串类型中定义好的compareTo方法result = result == 0 ? this.name.compareTo(o.name) : result;return result;}
}

测试类:

package test01;import java.util.Set;
import java.util.TreeSet;public class TreeSetTest01 {public static void main(String[] args) {Set<Student> t1 = new TreeSet<>();Student s1 = new Student("zhangsan",11);Student s2 = new Student("lisi",13);Student s3 = new Student("wangwu",11);Student s4 = new Student("linchuqiao",21);t1.add(s1);t1.add(s2);t1.add(s3);t1.add(s4);for (Student s : t1) {System.out.println(s);}}
}

运行结果:

⭕比较排序器Comparator的使用

Comparator也是一个接口,但是需要在带参构造方法使用

实现步骤
  • 用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的

  • 比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法

  • 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

代码示例:

要修改默认排序,先对字符串长度排序

package test01;import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;public class TreeSetTest02 {public static void main(String[] args) {Set<String> set = new TreeSet<>(new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {int result = o1.length() - o2.length();return result == 0 ? o1.compareTo(o2) : result;}});set.add("guangzhou");set.add("chongqing");set.add("beijing");set.add("shanghai");for (String s : set) {System.out.println(s);}}
}

运行结果:

String原先实现了Comparable接口,但是为了修改默认排序采用了Comparator比较器,由此可知第二种和第一种方法同时存在的话会遵循第二种方法(Comparator比较器)。

⭕两种排序方法总结
  • 自然排序: 自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序

  • 比较器排序: 创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序

  • 在使用的时候,默认使用自然排序,当自然排序不满足现在的需求时,必须使用比较器排序(一般是需要修改已经在源码中写好的排序规则,如String等类型的对象

两种方式中关于返回值的规则:

  • 如果返回值为负数,表示当前存入的元素是较小值,存左边

  • 如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存

  • 如果返回值为正数,表示当前存入的元素是较大值,存右边


七、全文总结

Collection 接口及其子接口 ListSet 构成了 Java 集合框架的核心部分,它们通过不同的实现类为我们提供了灵活的方式来处理数据。理解各个集合类的特点和适用场景,能够帮助开发者高效地组织和操作数据。

7.1 Collection集合性能对比总结

操作ArrayListLinkedListHashSetTreeSet
添加元素较快较快(首尾)较慢(排序)
删除元素较慢较快(首尾)较慢
查找元素较慢(首尾快)较慢
元素存取顺序有序有序无序可排序

在实际开发中,选择合适的集合类是非常重要的。对于需要频繁查找、插入和删除的场景,应根据数据结构的特点选择合适的实现类。

通过本文的介绍,你应该能够初步掌握 Java 中 Collection 单列集合的基础知识,并且学会如何选择适合的集合类进行开发。在实际项目中,合理使用集合将有助于提升代码的性能和可维护性噢!~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/437308.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker学习笔记(1.0)

docker命令 下载镜像相关命令 检索&#xff1a;docker search 比如&#xff1a;docker search nginx 是查看有没有nginx镜像 后面的OK表示是不是官方镜像&#xff0c;如果有就是官方镜像&#xff0c;如果没有就是第三方的。 下载&#xff1a;docker pull 比如&#xff1a…

【09】纯血鸿蒙HarmonyOS NEXT星河版开发0基础学习笔记-Class类基础全解(属性、方法、继承复用、判断)

序言&#xff1a; 本文详细讲解了关于我们在程序设计中所用到的class类的各种参数及语法。 笔者也是跟着B站黑马的课程一步步学习&#xff0c;学习的过程中添加部分自己的想法整理为笔记分享出来&#xff0c;如有代码错误或笔误&#xff0c;欢迎指正。 B站黑马的课程链接&am…

Windows开发工具使用技巧

在 Windows 上进行开发时&#xff0c;有许多工具和技巧可以提升开发效率和用户体验。以下是一些常用的开发工具和技巧&#xff1a; 常用开发工具 1. Visual Studio Code (VS Code) - 插件管理&#xff1a;利用扩展市场&#xff08;Extension Marketplace&#xff09;安装各种…

centos磁盘逻辑卷LVM创建

centos磁盘逻辑卷LVM创建 一、磁盘逻辑卷LVM说明二、centos磁盘使用情况三、LVM安装指南1.LVM工具安装1. yum list lvm2. yum search lvm3. yum search pvcreate4. yum list lvm25. yum install lvm2 2.创建物理卷2.1磁盘情况查看2.2创建物理卷&#xff08;PV&#xff09; 3.创…

【CKA】一、基于角色的访问控制-RBAC

1、基于角色的访问控制-RBAC 1. 考题内容&#xff1a; 2. 答题思路&#xff1a; 这道题就三条命令&#xff0c;建议直接背熟就行。 也可以查看帮助 kubectl create clusterrole -h kubectl create serviceaccount -h kubectl create rolebinding -h 注意&#xff1a; 1、资…

windows 桌面采集音频

头文件&#xff1a; #ifndef __CAPTURE_AUDIO__ #define __CAPTURE_AUDIO__#include <functional> #include <windows.h> #pragma comment(lib, "winmm.lib")class CaptureAudio { public:CaptureAudio();~CaptureAudio();public:bool Init(const std::…

uniapp中uni.request的统一封装 (ts版)

文章目录 前言一、我们为什么要去封装&#xff1f;二、具体实现1.创建一个请求封装文件&#xff1a;2.封装 uni.request&#xff1a;3.如何去使用&#xff1f; 总结 前言 在uniapp中如何去更简洁高效的发送我们的请求&#xff0c;下面就介绍了uni.request()二次封装。 一、我们…

C++ | Leetcode C++题解之第446题等差数列划分II-子序列

题目&#xff1a; 题解&#xff1a; class Solution { public:int numberOfArithmeticSlices(vector<int> &nums) {int ans 0;int n nums.size();vector<unordered_map<long long, int>> f(n);for (int i 0; i < n; i) {for (int j 0; j < i;…

音视频入门基础:FLV专题(7)——Tag header简介

一、引言 从《音视频入门基础&#xff1a;FLV专题&#xff08;3&#xff09;——FLV header简介》中可以知道&#xff0c; 在FLV header之后&#xff0c;FLV文件剩下的部分应由PreviousTagSize和Tag组成。FLV文件 FLV header PreviousTagSize0 Tag1 PreviousTagSize1 Ta…

最新BurpSuite2024.9专业中英文开箱即用版下载

1、工具介绍 本版本更新介绍 此版本对 Burp Intruder 进行了重大改进&#xff0c;包括自定义 Bambda HTTP 匹配和替换规则以及对扫描 SOAP 端点的支持。我们还进行了其他改进和错误修复。 Burp Intruder 的精简布局我们对 Burp Intruder 进行了重大升级。现在&#xff0c;您可…

【Canvas与徽章】金圈蓝底国庆75周年徽章

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>金边黑盾75周年</title><style type"text/css"&g…

sql语句牛客练习

文章目录 1. SQL21 浙江大学用户题目回答情况① 错误② 正确 2. SQL22 统计每个学校的答过题的用户的平均答题数① 错误② 正确 3. SQL23 统计每个学校各难度的用户平均刷题数4. SQL25 查找山东大学或者性别为男生的信息① 错误② 正确 5. SQL26 计算25岁以上和以下的用户数量①…

Linux相关概念和重要知识点(11)(进程调度、Linux内核链表)

1.Linux调度算法 上篇文章我粗略讲过queue[140]的结构&#xff0c;根据哈希表&#xff0c;我们可以将40个不同优先级的进程借助哈希桶链入queue[140]中。调度器会根据queue的下标来进行调度。但这个具体的调度过程是怎样的呢&#xff1f;以及runqueue和queue[140]的关系是什么…

DC00025【含论文】基于协同过滤推荐算法springboot视频推荐管理系统

1、项目功能演示 DC00025【含文档】基于springboot短视频推荐管理系统协同过滤算法视频推荐系统javaweb开发程序设计vue 2、项目功能描述 短视频推荐系统分为用户和系统管理员两个角色 2.1 用户角色 1、用户登录、用户注册 2、视频中心&#xff1a;信息查看、视频收藏、点赞、…

Leecode热题100-84.柱状图中的最大矩形

给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&#xff1a;heights [2,1,5,6,2,3] 输出&#xff1a;10 解释&#xff1a;最大的矩形为图…

Python核心知识:pip使用方法大全

什么是 pip&#xff1f; pip 是 Python 的包管理工具&#xff0c;允许用户安装、升级和管理 Python 的第三方库和依赖。它极大地简化了开发过程&#xff0c;使开发者可以轻松地获取并安装所需的软件包。pip 已成为 Python 项目中最常见的包管理工具&#xff0c;并且自 Python …

SQL第10课挑战题

1. 从OrderItems表中返回每个订单号order_num各有多少行数order_lines&#xff0c;并按order_lines对结果进行排序 2. 返回名为cheapest_item的字段&#xff0c;该字段包含每个供应商成本最低的产品&#xff08;使用products表中的prod_price)&#xff0c;然后从最低成本到最高…

房屋水电费:重新布局,重构JS代码

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>房租水电费</title><script type"…

计算机网络:计算机网络概述:网络、互联网与因特网的区别

文章目录 网络、互联网与因特网的区别网络分类 互联网因特网基于 ISP 的多层次结构的互连网络因特网的标准化工作因特网管理机构因特网的组成 网络、互联网与因特网的区别 若干节点和链路互连形成网络&#xff0c;若干网络通过路由器互连形成互联网 互联网是全球范围内的网络…

「安装」 Windows下安装CUDA和Pytorch

「安装」 Windows下安装CUDA和Pytorch 文章目录 「安装」 Windows下安装CUDA和PytorchMac、Linux、云端Windows安装CUDA安装miniconda安装PyTorch测试总结 其他 Mac、Linux、云端 Mac、Linux、云端安装Miniconda和Pytorch的方法参考其他资料。 Windows 下面进行Windows下安装…