JavaEE - 集合 - Collection集合
集合
集合是Java API所提供的一系列类,可以用于动态存放多个对象 (集合只能存对象)
集合类全部支持泛型,是一种数据安全的用法。
集合和数组的区别:
- 长度区别:数组固定、集合可变
- 内容区别:
- 数组可以是基本类型,也可以是引用类型
- 集合只能是引用类型
- 元素内容:
- 数组只能存储同一种类型
- 集合可以存储不同类型(集合一般也只存储同一种类型)
集合框架结构图
Collection
接口的接口,对象的集合(单列集合)
Collection集合的方法
方法 | 描述 |
---|---|
boolean add(E e) | 在集合末尾添加元素 |
boolean remove(Object o) | 若本类集中有值与o的值相等的元素,则删除该元素,并返回true |
void clear() | 清除本类集中所有元素,调用完该方法后本类集将为空。 |
boolean contains(Object o) | 判断集合中是否包含某元素 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 返回集合中的元素个数 |
boolean addAll(Collection c) | 将一个类集c中的所有元素添加到另一个类集 |
Object[] toArray() | 返回一个包含了本类集中所有元素的数组 |
Iterator iterator() | 选代器,集合的专用遍历方式 |
List接口
特点:元素按进入先后有序保存,可重复(因为List接口中添加了许多针对下标操作的方法)
ArrayList 底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素
LinkedList 底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素
Vector 底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素
- Stack 是Vector类的实现类
List特有功能
方法 | 描述 |
---|---|
void add(int index, Object obj) | 在指定位置添加元素 |
Object remove(int index) | 根据指定索引删除元素,并把删除的元素返回 |
Object set(int index, Object obj) | 把指定索引位置的元素修改为指定的值,返回修改前的值。 |
int indexOf(Object o) | 返回指定元素在集合中第一次出现的索引 |
Object get(int index) | 获取指定位置的元素 |
ListIterator listIterator() | 列表迭代器 |
List subList(int formIndex, int toIndex) | 截取集合 |
ArrayList
ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
ArrayList 继承了 AbstractList ,并实现了 List 接口。
ArrayList 类位于 java.util 包中,使用前需要引入它,语法格式如下:
// 引入 ArrayList 类
import java.util.ArrayList;
//创建Arraylist对象
ArrayList<E> list =new ArrayList<>();
ArrayList 是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
//创建Arraylist对象
ArrayList<String> list = new ArrayList<>();
//添加数据
list.add("加藤惠");
list.add("英梨梨");
list.add("樱泽墨");//在下标1处添加数据
list.add(1, "千鹤");//相当于["加藤惠","千鹤","英梨梨","樱泽墨"]
//获取长度
int size = list.size();//4
//设置指定下标处的数据
list.set(2, "蕾姆");//相当于["加藤惠","千鹤","蕾姆","樱泽墨"]
//获取指定下标处的数据
String name = list.get(3);//樱泽墨//清空集合
list.clear();//将新集合中所有的元素添加到现有集合中
ArrayList<String> newList = new ArrayList<>();
//利用集合工具类做批量添加
Collections.addAll(newList, "麻衣", "真白", "瑠夏");
list.addAll(newList);//相当于["麻衣","真白","瑠夏"]//将新集合中所有的元素添加到现有集合中指定下标的位置
ArrayList<String> newList2 = new ArrayList<>();
//利用集合工具类做批量添加
Collections.addAll(newList2, "x", "y", "z");
list.addAll(2, newList2);//相当于["麻衣","真白","x","y","z","瑠夏"]System.out.println("判断集合中是否有某个元素:" + list.contains("麻衣"));//true
System.out.println("判断现有集合中是否包含新集合中所有的元素:" + list.containsAll(newList2));//true
System.out.println("查询元素在集合中的下标:" + list.indexOf("瑠夏"));//5 查询不到就返回-1
System.out.println("判断集合是否为空:" + list.isEmpty());//false 为空-true 不为空-false//删除
//依据下标删除
list.remove(3);//相当于["麻衣","真白","x","z","瑠夏"]
//依据元素删除
list.remove("z");//相当于["麻衣","真白","x","瑠夏"]
//删除现有集合中和新集合共有的元素(删除交集)
list.removeAll(newList2);//相当于["麻衣","真白","瑠夏"]ArrayList<String> newList3 = new ArrayList<>();
//利用集合工具类做批量添加
Collections.addAll(newList3, "瑠夏", "真白", "莱卡");
//只保留交集
list.retainAll(newList3);//相当于["真白","瑠夏"]//将集合转换为数组
Object[] array = list.toArray();
//返回指定数组的字符串表示形式
System.out.println(Arrays.toString(array));//["真白","瑠夏"]//遍历1 - for
for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));
}
//遍历2 - foreach
for (String str : list) {System.out.println(str);
}
//遍历3 - 迭代器
Iterator<String> it = list.iterator();
while (it.hasNext()) {//判断是否有可迭代的元素String next = it.next();//返回下一个元素System.out.println(next);
}
//遍历4 - 迭代器(List的实现类独有的迭代器)
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()) {//判断是否有可迭代的元素String next = listIterator.next();System.out.println(next);
}
LinkedList
链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。
与 ArrayList 相比,LinkedList 的增加和删除对操作效率更高,而查找和修改的操作效率较低。
特有方法 | 描述 |
---|---|
void addFirst()、addLast() | 在列表开头/结尾添加元素 |
E removeFirst()、removeLast() | 在列表开头/结尾移除元素,并返回 |
E getFirst()、getLast() | 获取列表开头/结尾的元素 |
LinkedList 类位于 java.util 包中,使用前需要引入它,语法格式如下:
// 引入LinkedList类
import java.util.LinkedList;
// 创建LinkedList对象
LinkedList<E> list = new LinkedList<>();
更多的情况下我们使用 ArrayList 访问列表中的随机元素更加高效,但以下几种情况 LinkedList 提供了更高效的方法。
//创建LinkedList对象
LinkedList<String> list = new LinkedList<>();
//利用集合工具类做批量添加
Collections.addAll(list, "瑠夏1", "瑠夏2", "瑠夏3");
//在列表开头添加元素
list.addFirst("莱卡0");
//在列表结尾添加元素
list.addLast("莱卡4");
//遍历 - foreach
for (String str : list) {System.out.println(str);
}//获取列表开头的元素
System.out.println(list.getFirst());//莱卡0
//获取列表结尾的元素
System.out.println(list.getLast());//莱卡4//删除
LinkedList<String> list2 = new LinkedList<>();
//利用集合工具类做批量添加
Collections.addAll(list2, "樱泽墨1", "樱泽墨2", "樱泽墨3");
//队列模式 - 先进先出
while (!list2.isEmpty()) {//在列表开头移除元素,并返回String name = list2.removeFirst();System.out.println(name);
}
System.out.println("集合长度:" + list2.size());//0LinkedList<String> list3 = new LinkedList<>();
//利用集合工具类做批量添加
Collections.addAll(list3, "瑠夏1", "瑠夏2", "瑠夏3");
//栈模式 - 先进后出
while (!list3.isEmpty()) {//在列表结尾移除元素,并返回String name = list3.removeLast();System.out.println(name);
}
System.out.println("集合长度:" + list3.size());//0
Vector
概念:Vector是JDK1.0就有的集合类(元老级别),集合框架的概念是JDK1.2出现的,设计者为了将Vector保留下,所以让Vector实现了List接口。目前已弃用
特有方法 | 描述 |
---|---|
void addElement(E obj) | 相当于add() |
boolean removeElement(Object obj) | 相当于remove() |
E elementAt(int index) | 相当于get() |
Enumeration<E> elements() | 相当于iterator() |
//创建Vector对象
Vector<String> v = new Vector<>();
v.addElement("哈尔卡拉");
v.addElement("加藤惠");
v.addElement("樱泽墨");
//依据元素删除
v.removeElement("加藤惠");
//依据下标删除
v.removeElementAt(0);
//返回指定索引处的元素。
System.out.println(v.elementAt(0));//哈尔卡拉
//实现 Enumeration 接口的对象一次生成一系列元素。
//对 nextElement 方法的连续调用将返回系列的连续元素。
Enumeration<String> elements = v.elements();
while (elements.hasMoreElements()) {//测试此枚举是否包含更多元素。String nextElement = elements.nextElement();System.out.println(nextElement);
}
Stack
注意:Stack extends Vector
特点:栈模式-先进后出
方法 | 描述 |
---|---|
E push(E item) | 把项(元素)压入 栈顶 。相当于addElement(item) |
int search(Object o) | 查询元素到 栈顶 的距离,从1开始 |
E pop() | 删除 栈顶 第一个元素,并返回 |
//创建Stack对象
Stack<String> stack = new Stack<>();
//把项(元素)压入栈顶
stack.push("哈尔卡拉");
stack.push("加藤惠");
stack.push("樱泽墨");
//查询(查询元素到栈顶的距离,从1开始)
int index = stack.search("哈尔卡拉");
System.out.println(index);//3
//遍历
while (!stack.empty()) {//判断集合是否没有元素String pop = stack.pop();//删除栈顶第一个元素,并返回System.out.println(pop);
}
Set接口
特点:仅接收一次,不可重复,并做内部排序
- HashSet 使用hash表(数组)存储元素
- LinkedHashSet 链表维护元素的插入次序
- TreeSet 底层实现为二叉树,元素自动排序
无特有功能: 可使用Collection方法
HashSet
HashSet 底层数据结构采用哈希表实现,元素无序且唯一,线程不安全,效率高,可以存储null元素,元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证
HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。
HashSet中的数据是无序的,可以放入null,但只能放入一个null
HashSet放入的对象,是以hashcode码作为标识的,而具有相同内容的String对象,hashcode是一样,所以放入的内容不能重复。
// 引入 HashSet 类
import java.util.HashSet;
// 创建HashSet对象
HashSet<String> set = new HashSet<>();
理解HashSet为什么是无序且不可重复
无序:存入顺序和取出顺序不一致,无序不代表随机
- 存入顺序:根据对象的hash值,再通过散列算法计算出在数组中的下标
- 取出顺序:遍历数组
不可重复:存储元素首先会使用hash()算法生成一个int类型hashCode,然后和已经存储元素的hashCode值比较,如果hashCode不相等,存储当前新的hashCode值处的元素对象;如果hashCode相等,存储元素的对象不一定相等,此时会调用equals()方法判断两个对象的内容是否相等,如果相等,就是同一个对象,无需存储;如果比较的内容不相等,就是不同的对象,就存储,此时就要采用哈希解决地址冲突算法,在当前hashCode值处增加一个新的链表, 在同一个hashCode值的后面存储不同的对象,这样就保证了元素的唯一性。
LinkedHashSet
LinkedHashSet 底层数据结构采用链表和哈希表共同实现,链表保证了元素的顺序与存储顺序一致,哈希表保证了元素的唯一性。线程不安全,效率高。
// 引入 LinkedHashSet 类
import java.util.LinkedHashSet;
// 创建LinkedHashSet对象
LinkedHashSet<String> set = new LinkedHashSet<>();
理解LinkedHashSet为什么是有序
- 存入顺序:根据对象的hash值,再通过散列算法计算出在数组中的下标,存入元素时记录上一个节点的地址
- 取出顺序:遍历最开始的节点,因为每个节点都找到得到上一个节点和下一个节点,所以是有序的
TreeSet
TreeSet 底层数据结构采用二叉树(红黑树)来实现,元素唯一且自动排序 ,不允许放入null值;唯一性同样需要重写hashCode和equals()方法。
根据构造方法不同,分为自然排序(无参构造)和比较器排序(有参构造),自然排序要求元素必须实现Comparable接口,并重写里面的compareTo()方法,元素通过比较返回的int值来判断排序序列,返回0说明两个对象相同,不需要存储;
// 引入 TreeSet 类
import java.util.TreeSet;
//创建TreeSet对象
TreeSet<String> set = new TreeSet<>();
理解TreeSet自然排序
含义:根据不同的类型选择不同的排序规则
TreeSet存储Integer:数字升序
TreeSet存储String:字典排序
TreeSet<Integer> set1 = new TreeSet<>();
set1.add(4);
set1.add(2);
set1.add(3);
set1.add(3);//重复元素不会被添加
for (Integer integer : set1) {System.out.println(integer);
}
//2
//3
//4TreeSet<String> set2 = new TreeSet<>();
set2.add("bd");
set2.add("cde");
set2.add("ac");
for (String string : set2) {System.out.println(string);
}
//ac
//bd
//cde
比较器接口
作用:排序时使用
内置比较器:Comparable - compareTo()
外置比较器:Comparator - compare()
使用场景:
内置比较器:对象要想存入TreeSet、TreeMap中,对象所属的类必须要实现内置比较器
外置比较器:当内置比较的规则不满足现在的需求,但又不能改动内置比较器规则时
TeeSet使用内置排序接口
Student.java
//实现Comparable接口
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;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}//重写compareTo()方法@Overridepublic int compareTo(Student o) {return this.age-o.age;}
}
Test.java
TreeSet<Student> set = new TreeSet<>();
set.add(new Student("艾米莉娅", 18));
set.add(new Student("樱泽墨", 17));
set.add(new Student("本间芽衣子", 15));
for (Student stu : set) {System.out.println(stu);
}
//Student [name=本间芽衣子, age=15]
//Student [name=樱泽墨, age=17]
//Student [name=艾米莉娅, age=18]
TeeSet使用外置排序接口
需求:按照名字长度排序,长度一致按照年龄排序
TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {if(o1.getName().equals(o2.getName()) && o1.getAge() == o2.getAge()){return 0;}if(o1.getName().length() != o2.getName().length()){return o1.getName().length() - o2.getName().length();}if(o1.getAge() == o2.getAge()){return 1;}return o1.getAge() - o2.getAge();}
});
set.add(new Student("艾米莉娅", 18));
set.add(new Student("樱泽墨", 17));
set.add(new Student("椎名真白", 17));
set.add(new Student("本间芽衣子", 15));
for (Student stu : set) {System.out.println(stu);
}
//Student [name=樱泽墨, age=17]
//Student [name=椎名真白, age=17]
//Student [name=艾米莉娅, age=18]
//Student [name=本间芽衣子, age=15]
Collections工具类
Collections提供以下方法对List进行排序操作
方法 | 描述 |
---|---|
boolean addAll(Collection<? super T> c, T…elements) | 将所有指定的元素添加到指定的集合 |
void reverse(List list) | 反转 |
void shuffle(List list) | 随机排序 |
void sort(List list) | 按自然排序的升序排序 |
void sort(List list, Comparator c) | 定制排序,由Comparator控制排序逻辑 |
T min(Collection<? extends T> coll) | 根据元素的自然顺序返回给定集合的最小元素 |
T max(Collection<? extends T> coll) | 根据元素的自然顺序返回给定集合的最大元素 |
ArrayList<Integer> nums = new ArrayList<>();
//将所有指定的元素添加到指定的集合
Collections.addAll(nums, 8, -3, 2, 9, -2);
System.out.println("集合:" + nums);
Collections.reverse(nums);
System.out.println("翻转集合:" + nums);
Collections.sort(nums);
System.out.println("自然排序(内置比较器):" + nums);
Collections.shuffle(nums);
System.out.println("随机排序:" + nums);
//排序 - 使用外置比较器
Collections.sort(nums, new Comparator() {@Overridepublic int compare(Object o1, Object o2) {//比较它的两个参数的顺序String s1 = String.valueOf(o1);String s2 = String.valueOf(o2);//按字典顺序比较两个字符串return s1.compareTo(s2);}
});
System.out.println(nums);
System.out.println("获取最小值:" + Collections.min(nums));
System.out.println("获取最大值:" + Collections.max(nums));
//集合:[8, -3, 2, 9, -2]
//翻转集合:[-2, 9, 2, -3, 8]
//自然排序(内置比较器):[-3, -2, 2, 8, 9]
//随机排序:[-3, 2, 9, -2, 8]
//[-2, -3, 2, 8, 9]
//获取最小值:-3
//获取最大值:9
适用场景
泛型
泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
- 所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前(如
<E>
) - 每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符
- 类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符
- 泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(像int,double,char的等)
public static void main(String args[]) {// 创建不同类型数组: Integer, Double 和 CharacterInteger[] intArray = {1, 2, 3, 4, 5};Double[] doubleArray = {1.1, 2.2, 3.3, 4.4};Character[] charArray = {'H', 'E', 'L', 'L', 'O'};System.out.println("整型数组元素为:");printArray(intArray); // 传递一个整型数组System.out.println("\n双精度型数组元素为:");printArray(doubleArray); // 传递一个双精度型数组System.out.println("\n字符型数组元素为:");printArray(charArray); // 传递一个字符型数组
}
// 泛型方法 printArray
public static <E> void printArray(E[] inputArray) {// 输出数组元素for (E element : inputArray) {System.out.printf("%s ", element);}
}
//整型数组元素为:
//1 2 3 4 5
//双精度型数组元素为:
//1.1 2.2 3.3 4.4
//字符型数组元素为:
//H E L L O
泛型限定:
?
表示什么类型都可以
? extends A
表示元素必须是A类或A的子类
? super A
表示元素必须是A类或A的父类
//?表示什么类型都可以
public static ArrayList<?> method01() {ArrayList<Integer> list = new ArrayList<>();list.add(100);return list;
}
//前提B继承A
//? extends A 表示元素必须是A类或A的子类
public static ArrayList<? extends A> method02() {// ArrayList<A> list = new ArrayList<>();ArrayList<B> list = new ArrayList<>();return list;
}
//? super A 表示元素必须是A类或A的父类
public static ArrayList<? super A> method03() {// ArrayList<A> list = new ArrayList<>();ArrayList<Object> list = new ArrayList<>();return list;
}
迭代器
Iterator是一种用于访问集合的方法,可用于迭代 ArrayList 和 HashSet 等集合。
Iterator 是 Java 迭代器最简单的实现,ListIterator 是 Collection API 中的接口, 它扩展了 Iterator 接口。
不能在迭代器中使用集合对象删除元素
foreach底层由迭代器实现
ArrayList<String> list = new ArrayList<>();
list.add("樱岛麻衣");
list.add("椎名真白");
list.add("艾米莉娅");
for (String element : list) {System.out.println(element);
}
//底层实现:
// String element;
// for (Iterator<String> it = list.iterator(); it.hasNext(); System.out.println(element)) // {// element = it.next();
// }
Iterator
// 创建集合
ArrayList<Integer> nums = new ArrayList<>();
nums.add(2);
nums.add(6);
nums.add(23);
nums.add(12);
// 获取Iterator迭代器
Iterator<Integer> it = nums.iterator();
while (it.hasNext()) {//如果迭代有更多元素,则返回trueInteger i = it.next();//next()返回迭代中的下一个元素//删除集合中小于 10 的元素if (i < 10) {//不能在迭代器中使用集合对象删除元素//nums.remove(i);it.remove();//删除元素}
}
System.out.println(nums);//[23, 12]
ListIterator
// 创建集合
ArrayList<Integer> nums = new ArrayList<>();
nums.add(6);
nums.add(15);
nums.add(25);
nums.add(10);
// 获取ListIterator迭代器
ListIterator<Integer> it = nums.listIterator();
while (it.hasNext()) {//如果迭代有更多元素,则返回trueInteger i = it.next();//next()返回迭代中的下一个元素//删除集合中小于10的元素if (i < 10) {it.remove();//删除元素}//集合中大于20的元素修改成30if (i > 20) {it.set(30);//修改元素}//在集合中15的后面添加16if (i == 15) {it.add(16);//添加元素}
}
System.out.println(nums);//[15, 16, 30, 10]
//从第3个元素开始使用迭代器遍历
ListIterator<Integer> it2 = nums.listIterator(2);
while (it2.hasNext()) {Integer next = it2.next();System.out.printf("%d ", next);
}//30 10
System.out.println();
//倒叙输出
ListIterator<Integer> it3 = nums.listIterator(nums.size());
while (it3.hasPrevious()) {//判断是否有上一个可迭代的元素Integer previous = it3.previous();//返回上一个元素System.out.printf("%d ", previous);
}//10 30 16 15
Iterator 和 ListIterator 区别
Iterator :Collection接口下所有的实现类都可以获取的迭代器,可以在遍历时删除元素
ListIterator :List接口下所有的实现类可以获取的迭代器,可以在遍历时删除、修改、添加元素,也可以指定下标开始遍历,还可以倒叙遍历
JavaEE - 集合 - Collection集合相关推荐
- 集合(Collection集合)由来
一.集合(Collection集合) (1)集合的由来? 我们学习的是Java – 面向对象 – 操作很多对象 – 存储 – 容器(数组和StringBuffer) – 数组 而数组的长度固定,所以不 ...
- Day15 --框架集合 Collection集合 和 List 集合
a. 对象数组 --自定义对象类 概述 * 创建一个自定义类用于存储学生信息,并且获取到每个学生信息 . 使用 ...
- 高级API(UDP连接Map集合Collection集合)
.UDP协议: DatagramSocket---该对象可以代表接收端也可以代表发送端 DatagramPacket-----数据打包对象(数据报对象--将发送的内容通过该对象进行打包,在通过指定的方 ...
- 集合 (一) ----- 集合的基本概念与Collection集合详解
相关文章: <集合 (一) ----- 集合的基本概念与Collection集合详解> <集合 (二) ----- Map集合详解> 文章目录 集合的基本概念 一.集合的分类 ...
- Java 基础 Collection集合
package cn.itcast.demoDateformat;import java.util.ArrayList; import java.util.Collection;/* * List接口 ...
- collection集合和源码
集合 collection集合 map list集合三种循环 List<String> list = new ArrayList<>();list.add("1&qu ...
- regex和集合(collection)
一.regex 需求:校验一个QQ号码 定义一个规则:1)由5到10为组成的数字 2)不能以0开头 分析: 1)键盘录入一个QQ号码,使用字符串接收 2)定义一个校验Q ...
- 集合collection
集合体系结构 1.Collection 1.1.collection集合概述和使用 collection集合概述 Collection是单列集合的顶层接口,他表示一组对象,这些对象也称为Collect ...
- JAVASE-17:集合Collection、List
集合 数组作为容器的不好之处 就是对容器中的元素进行操作时,不够方便,比如要增删数组中的元素,就不是那么方便了,因为数组一单定义,长度就不能改变了,JAVA为了我们更方便去操作容器中的元素,提供了一种 ...
- java集合Collection
文章目录 ==Collection集合== Collection概述 Collection集合常用方法 Collection集合的遍历之iterator 概述 Iterator中的常用方法 集合使用步 ...
最新文章
- MySql按周,按月,按日分组统计数据
- 空地通信传输详解——飞机是这样和地面通信的
- 我拍了拍 Redis,没想到被移出了群聊......
- css和JavaScript
- mysql alter算法_MySQL ALTER命令_mysql alter_添加_删除_修改
- 【网络安全】令人闻风丧胆的“木马”是个啥来头?
- spring boot整合mybatis+通用mapper+pagehelper分页插件
- centos7安装ddos-deflate
- 3w并发mysql架构_(DBA之路【一】)mysql 基本架构
- 安卓系统挂载NTFS格式硬盘_Mac 读写 NTFS硬盘管理开源工具NTFSTool
- pythonselenium提高爬虫效率_[编程经验] Python中使用selenium进行动态爬虫
- Android 系统(77)---MVC,MVP,MVVM的区别
- Python,Day2 - 数据类型,运算,列表操作,字典
- 计算机组成原理复习要点与考题类型--选择-填空-分析-计算-简答
- 期刊论文发表的字数不够怎么办
- 学习C++可以做什么,可以从事哪些领域的工作
- 全球与中国汽车线性稳压器市场运营状况及未来前景展望报告2022-2028年版
- 未来时代量计算机科幻游戏,“八本科幻未来时代小说”到那个我们可以想象的极限,享受科幻美...
- 洛谷3964 松鼠聚会
- win10或win11右键管理找不到文件解决