当前位置: 首页 > article >正文

Java单列集合[Collection]

目录

1.Collection单列集合

1.1单列集合各集合特点

1.2、Collection集合

1.2.1、Collection方法

1.2.2、Collection遍历方式

1.2.2.1、迭代器遍历集合

1.2.2.2、增强for遍历集合

1.2.2.3、forEach遍历集合(JDK8之后)

1.2.2.4、遍历案例

1.3、List系列集合(List、ArrayList、LinkedList)

1.3.1、List集合的常用方法

1.3.2、List集合的遍历方式

 1.3.3、ArrayList集合

1.3.4、LinkedList

1.3.4.1、LinkedList常用方法、

使用LinkedList设计栈结构、队列结构

1.4、Set系列集合(Set、HashSet、LinkedHashSet、TreeSet)

1.4.1、HashSet集合

1.4.1.1、底层原理(了解)

1.4.1.2、HashSet去重原理(重写hashcode、equals方法)

1.4.2、LinkedHashSet集合

1.4.3、TreeSet集合

2、各集合使用情况

3、集合的并发修改异常

3.1解决方法

4、Collection其他使用

4.1、可变参数

4.2、Collections工具类


集合分为单列集合和双列集合:

1.Collection单列集合

Collection 是单列集合的根接口, Collection 接口下面又有两个子接口List 接口、 Set 接口, List Set 下面分别有不同的实现类,如下图所示:

1.1单列集合各集合特点

可以自己写代码验证一下,各种集合的特点
// 简单确认一下 Collection 集合的特点
ArrayList<String> list = new ArrayList<>(); // 存取顺序一致,可以重复,有索引
list.add("java1");
list.add("java2");
list.add("java1");
list.add("java2");
System.out.println(list); //[java1, java2, java1, java2]
HashSet<String> list = new HashSet<>(); // 存取顺序不一致,不重复,无索引
list.add("java1");
list.add("java2");
list.add("java1");
list.add("java2");
list.add("java3");
System.out.println(list); //[java3, java2, java1]

1.2、Collection集合

1.2.1、Collection方法

所有 Collection单列集合的实现类都可以使用( ArrayListLinkedListHashSetLinkedHashSetTreeSet 集合都可以调用下面的方法。
Collection<String> c = new ArrayList<>();//1.public boolean add(E e): 添加元素到集合
c.add("java1");
c.add("java1");
c.add("java2");
c.add("java2");
c.add("java3");
System.out.println(c); //打印: [java1, java1, java2, java2, java3]//2.public int size(): 获取集合的大小
System.out.println(c.size()); //5//3.public boolean contains(Object obj): 判断集合中是否包含某个元素
System.out.println(c.contains("java1")); //true
System.out.println(c.contains("Java1")); //false//4.pubilc boolean remove(E e): 删除某个元素,如果有多个重复元素只能删除第一个
System.out.println(c.remove("java1")); //true
System.out.println(c); //打印: [java1,java2, java2, java3]//5.public void clear(): 清空集合的元素
c.clear();
System.out.println(c); //打印:[]//6.public boolean isEmpty(): 判断集合是否为空 是空返回true 反之返回false
System.out.println(c.isEmpty()); //true//7.public Object[] toArray(): 把集合转换为数组
Object[] array = c.toArray();
System.out.println(Arrays.toString(array)); //[java1,java2, java2, java3]//8.如果想把集合转换为指定类型的数组,可以使用下面的代码
String[] array1 = c.toArray(new String[c.size()]);
System.out.println(Arrays.toString(array1)); //[java1,java2, java2, java3]//9.还可以把一个集合中的元素,添加到另一个集合中
Collection<String> c1 = new ArrayList<>();
c1.add("java1");
c1.add("java2");
Collection<String> c2 = new ArrayList<>();
c2.add("java3");
c2.add("java4");c1.addAll(c2); //把c2集合中的全部元素,添加到c1集合中去
System.out.println(c1); //[java1, java2, java3, java4]

1.2.2、Collection遍历方式

1.2.2.1、迭代器遍历集合

代码演示:
Collection<String> c=new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("素素");
c.add("灭绝");
System.out.println(c); //[赵敏, 小昭, 素素, 灭绝]//第一步:先获取迭代器对象
//解释:Iterator就是迭代器对象,用于遍历集合的工具)
Iterator<String> it=c.iterator();

//第二步:用于判断当前位置是否有元素可以获取
//解释:hasNext()方法返回true,说明有元素可以获取;反之没有
while(it.hasNext()){//第三步:获取当前位置的元素,然后自动指向下一个元素.String e=it.next();System.out.println(s);}

迭代器代码的原理如下:
    当调用iterator()方法获取迭代器时,当前指向第一个元素hasNext()方法则判断这个位置是否有元素,如果有则返回true,进入循环调用next()方法获取元素,并将当月元素指向下一个位置,等下次循环时,则获取下一个元素,依此内推
1.2.2.2、增强for遍历集合

Collection<String> c = new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("素素");
c.add("灭绝");//1.使用增强for遍历集合
for(String s: c){System.out.println(s);
}//2.再尝试使用增强for遍历数组
String[] arr = {"迪丽热巴", "古力娜扎", "稀奇哈哈"};
for(String name: arr){System.out.println(name);
}
1.2.2.3、forEach遍历集合(JDK8之后)
JDK8 版本以后还提供了一个 forEach 方法也可以遍历集合,如果下图所示:
Collection<String> c = new ArrayList<>();
c.add("赵敏");
c.add("小昭");
c.add("素素");
c.add("灭绝");
//调用forEach方法
//由于参数是一个Consumer接口,所以可以传递匿名内部类
c.forEach(new Consumer<String>{@Overridepublic void accept(String s){System.out.println(s);}
});
1.2.2.4、遍历案例

首先,我们得写一个电影类,用来描述每一步电影应该有哪些信息:
public class Movie{private String name; //电影名称private double score; //评分private String actor; //演员//无参数构造方法public Movie(){}//全参数构造方法public Movie(String name, double score, String actor){this.name=name;this.score=score;this.actor=actor;}
//...get、set、toString()方法自己补上..
}
接着,再创建一个测试类,完成上面的需求:
public class Test{public static void main(String[] args){Collection<Movie> movies = new ArrayList<>();movies.add(new MOvie("《肖申克的救赎》", 9.7, "罗宾斯"));movies.add(new MOvie("《霸王别姬》", 9.6, "张国荣、张丰毅"));movies.add(new MOvie("《阿甘正传》", 9.5, "汤姆汉克斯"));for(Movie movie : movies){System.out.println("电影名:" + movie.getName());System.out.println("评分:" + movie.getScore());System.out.println("主演:" + movie.getActor());}}
}

1.3、List系列集合(List、ArrayList、LinkedList)

1.3.1、List集合的常用方法

接下来,我们用代码演示一下这几个方法的效果//1.创建一个ArrayList集合对象(有序、有索引、可以重复)
List<String> list = new ArrayList<>();
list.add("蜘蛛精");
list.add("至尊宝");
list.add("至尊宝");
list.add("牛夫人");
System.out.println(list); //[蜘蛛精, 至尊宝, 至尊宝, 牛夫人]//2.public void add(int index, E element): 在某个索引位置插入元素
list.add(2, "紫霞仙子");
System.out.println(list); //[蜘蛛精, 至尊宝, 紫霞仙子, 至尊宝, 牛夫人]//3.public E remove(int index): 根据索引删除元素, 返回被删除的元素
System.out.println(list.remove(2)); //紫霞仙子
System.out.println(list);//[蜘蛛精, 至尊宝, 至尊宝, 牛夫人]//4.public E get(int index): 返回集合中指定位置的元素
System.out.println(list.get(3));//5.public E set(int index, E e): 修改索引位置处的元素,修改后,会返回原数据
System.out.println(list.set(3,"牛魔王")); //牛夫人
System.out.println(list); //[蜘蛛精, 至尊宝, 至尊宝, 牛魔王]

1.3.2、List集合的遍历方式

List 集合相比于前面的 Collection 多了一种可以通过索引遍历的方式,所以 List 集合遍历方式一共有四种:
  • 普通for循环(只因为List有索引)
  • 迭代器
  • 增强for
  • forEach遍历Lambda表达式
List<String> list = new ArrayList<>();
list.add("蜘蛛精");
list.add("至尊宝");
list.add("糖宝宝");
//1.普通for循环
for(int i = 0; i< list.size(); i++){
//i = 0, 1, 2String e = list.get(i);System.out.println(e);
}
//2.增强for遍历
for(String s : list){System.out.println(s);
}
//3.迭代器遍历
Iterator<String> it = list.iterator();
while(it.hasNext()){String s = it.next();System.out.println(s);
}
//4.lambda表达式遍历
list.forEach(s->System.out.println(s));

 1.3.3、ArrayList集合

ArrayList 集合底层是基于数组结构实现的,也就是说当你往集合容器中存储元素时,底层本质上是往数组中存储元素。
我们知道数组的长度是固定的,但是集合的长度是可变的,这是怎么做到的呢?原理如下:

1.3.4、LinkedList

1.3.4.1、LinkedList常用方法、

LInkedList 集合有什么用呢?可以用它来设计栈结构、队列结构。
队列结构你可以认为是一个上端开口,下端也开口的管子的形状。元素从上端入 队列,从下端出队列。
使用LinkedList设计栈结构、队列结构

入队列可以调用 LinkedList 集合的 addLast 方法,出队列可以调用 removeFirst() 方法 .
//1.创建一个队列:先进先出、后进后出
LinkedList<String> queue = new LinkedList<>(); //这是linkedlist独有的所以不能多态
//入对列
queue.addLast("第1号人");
queue.addLast("第2号人");
queue.addLast("第3号人");
queue.addLast("第4号人");
System.out.println(queue);
//出队列
System.out.println(queue.removeFirst()); //第4号人
System.out.println(queue.removeFirst()); //第3号人
System.out.println(queue.removeFirst()); //第2号人
System.out.println(queue.removeFirst()); //第1号人
栈结构的特点是先进后出,后进先出

接着,我们就用LinkedList来模拟下栈结构,代码如下:
//1.创建一个栈对象
LinkedList<String> stack = new LinkedList<>();
//压栈(push) 等价于 addFirst()
stack.push("第1颗子弹");
stack.push("第2颗子弹");
stack.push("第3颗子弹");
stack.push("第4颗子弹");
System.out.println(stack); //[第4颗子弹, 第3颗子弹, 第2颗子弹,第1颗子弹]
//弹栈(pop) 等价于 removeFirst()
System.out.println(statck.pop()); //第4颗子弹
System.out.println(statck.pop()); //第3颗子弹
System.out.println(statck.pop()); //第2颗子弹
System.out.println(statck.pop()); //第1颗子弹
//弹栈完了,集合中就没有元素了
System.out.println(list); //[]

1.4、Set系列集合(Set、HashSet、LinkedHashSet、TreeSet)

每一种 Set 集合的特点。(自己在idea上体会)
//Set<Integer> set = new HashSet<>(); // 无序、无索引、不重复
//Set<Integer> set = new LinkedHashSet<>(); // 有序、无索引、不重复
Set < Integer > set = new TreeSet <> (); // 可排序 ( 升序 ) 、无索引、不重复
set . add ( 666 );
set . add ( 555 );
set . add ( 555 );
set . add ( 888 );
set . add ( 888 );
set . add ( 777 );
set . add ( 777 );
System . out . println ( set ); //[555, 666, 777, 888]

1.4.1、HashSet集合

1.4.1.1、底层原理(了解)

HashSet 集合中存储元素时,底层调用了元素的两个方法:一个是 hashCode 方法获取元素的 hashCode 值(哈希值);另一个是调用了元素的equals 方法,用来比较新添加的元素和集合中已有的元素是否相同。
  • 只有新添加元素的hashCode值和集合中以后元素的hashCode值相同、新添加的元素调用equals方法和集合中已有元素比较结果为true, 才认为元素重复。
  • 如果hashCode值相同,equals比较不同,则以链表的形式连接在数组的同一个索引为位置(如上图所示)
JDK8 开始后,为了提高性能,当链表的长度超过8时,就会把链表转换为红黑树,如下图所示:
1.4.1.2、HashSet去重原理(重写hashcode、equals方法)
HashSet 存储元素的原理,依赖于两个方法:一个是 hashCode 方法用来确定在底层数组中存储的位置,另一个是用equals 方法判断新添加的元素是否和集合中已有的元素相同。
要想保证在 HashSet 集合中没有重复元素,需要重写元素类的 hashCodeequals 方法。比如以下面的 Student 类为例,假设把Student 类的对象作为 HashSet 集合的元素,想要让学生的姓名和年龄相同,就认为元素重复。
public class Student{private String name; //姓名private int age; //年龄private double height; //身高//无参数构造方法public Student(){}//全参数构造方法public Student(String name, int age, double height){this.name=name;this.age=age;this.height=height;}//...get、set、toString()方法自己补上..
//按快捷键生成hashCode和equals方法
//alt+insert 选择 hashCode and equals@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;if (age != student.age) return false;if (Double.compare(student.height, height) != 0) return false;return name != null ? name.equals(student.name) : student.name == null;}@Overridepublic int hashCode() {int result;long temp;result = name != null ? name.hashCode() : 0;result = 31 * result + age;temp = Double.doubleToLongBits(height);result = 31 * result + (int) (temp ^ (temp >>> 32));return result;}
}
接着,写一个测试类,往 HashSet 集合中存储 Student 对象。
public class Test{public static void main(String[] args){Set<Student> students = new HashSet<>();Student s1 = new Student("至尊宝",20, 169.6);Student s2 = new Student("蜘蛛精",23, 169.6);Student s3 = new Student("蜘蛛精",23, 169.6);Student s4 = new Student("牛魔王",48, 169.6);students.add(s1);students.add(s2);students.add(s3);students.add(s4);for(Student s : students){System.out.println(s);}}
}

1.4.2、LinkedHashSet集合

HashSet 的子类 LinkedHashSet 类。 LinkedHashSet 它底层采用的是也是哈希表结构,只不
过额外新增了一个双向链表来维护元素的存取顺序。

public class Test{public static void main(String[] args){Set<Student> students = new LinkedHashSet<>();Student s1 = new Student("至尊宝",20, 169.6);Student s2 = new Student("蜘蛛精",23, 169.6);Student s3 = new Student("蜘蛛精",23, 169.6);Student s4 = new Student("牛魔王",48, 169.6);students.add(s1);students.add(s2);students.add(s3);students.add(s4);for(Student s : students){System.out.println(s);}}
}
打印结果如下

1.4.3、TreeSet集合

TreeSet 集合的特点是可以对元素进行排序,但是必须指定元素的排序规则。
1.如果往集合中存储 String类型的元素,或者Integer 类型的元素,它们本身就具备排序规则,所以直接就可以排序。
Set<Integer> set1= new TreeSet<>();
set1.add(8);
set1.add(6);
set1.add(4);
set1.add(3);
set1.add(7);
set1.add(1);
set1.add(5);
set1.add(2);
System.out.println(set1); //[1,2,3,4,5,6,7,8]Set<Integer> set2= new TreeSet<>();
set2.add("a");
set2.add("c");
set2.add("e");
set2.add("b");
set2.add("d");
set2.add("f");
set2.add("g");
System.out.println(set1); //[a,b,c,d,e,f,g]

2.如果往TreeSet集合中存储自定义类型的元素,比如说Student类型,则需要自己指定排序规则,否则会出现异常。

错误情况:

//创建TreeSet集合,元素为Student类型
Set<Student> students = new TreeSet<>();
//创建4个Student对象
Student s1 = new Student("至尊宝",20, 169.6);
Student s2 = new Student("紫霞",23, 169.8);
Student s3 = new Student("蜘蛛精",23, 169.6);
Student s4 = new Student("牛魔王",48, 169.6);
//添加Studnet对象到集合
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s4);
System.out.println(students);
此时运行代码,会直接报错。原因是 TreeSet 不知道按照什么条件对 Student 对象来排序。
正确写法:
我们想要告诉 TreeSet 集合按照指定的规则排序,有两种办法:
  • 第一种:让元素的类实现Comparable接口,重写compareTo方法
  • 第二种:在创建TreeSet集合时,通过构造方法传递Compartor比较器对象
排序方式 1
//第一步:先让Student类,实现Comparable接口
//注意:Student类的对象是作为TreeSet集合的元素的
public class Student implements Comparable<Student>{private String name;private int age;private double height;//无参数构造方法public Student(){}//全参数构造方法public Student(String name, int age, double height){this.name=name;this.age=age;this.height=height;}//...get、set、toString()方法自己补上..
//第二步:重写compareTo方法
//按照年龄进行比较,只需要在方法中让this.age和o.age相减就可以。
/*
原理:
在往TreeSet集合中添加元素时,add方法底层会调用compareTo方法,根据该方法的
结果是正数、负数、还是零,决定元素放在后面、前面还是不存。
*/ @Overridepublic int compareTo(Student o) {
//this:表示将要添加进去的Student对象
//o: 表示集合中已有的Student对象return this.age-o.age;}
}

此时,再运行测试类,结果如下Student{name='至尊宝', age=20, height=169.6}Student{name='紫霞', age=20, height=169.8}Student{name='蜘蛛精', age=23, height=169.6}Student{name='牛魔王', age=48, height=169.6}
排序方式 2
//创建TreeSet集合时,传递比较器对象排序
/*
原理:当调用add方法时,底层会先用比较器,根据Comparator的compare方是正数、负数、还是零,决定谁在后,谁在前,谁不存。
*/
//下面代码中是按照学生的年龄升序排序
Set<Student> students = new TreeSet<>(new Comparator<Student>{@Overridepublic int compare(Student o1, Student o2){//需求:按照学生的身高排序return Double.compare(o1,o2);}
});
//创建4个Student对象
Student s1 = new Student("至尊宝",20, 169.6);
Student s2 = new Student("紫霞",23, 169.8);
Student s3 = new Student("蜘蛛精",23, 169.6);
Student s4 = new Student("牛魔王",48, 169.6);
//添加Studnet对象到集合
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s4);
System.out.println(students);

2、各集合使用情况

3、集合的并发修改异常

其实就是删除一个元素后,集合位置会发生改变,但是索引接着往下走产生的原因,导致有些数据没办法被索引指到的问题

在使用迭代器遍历集合时,可能存在并发修改异常。
我们先把这个异常用代码演示出来,再解释一下为什么会有这个异常产生
List<String> list = new ArrayList<>();
list.add("王麻子");
list.add("小李子");
list.add("李爱花");
list.add("张全蛋");
list.add("晓李");
list.add("李玉刚");
System.out.println(list); // [王麻子, 小李子, 李爱花, 张全蛋, 晓李, 李玉刚]//需求:找出集合中带"李"字的姓名,并从集合中删除
Iterator<String> it = list.iterator();
while(it.hasNext()){String name = it.next();if(name.contains("李")){ list.remove(name);}
}
System.out.println(list);

运行上面的代码,会出现下面的异常。这就是并发修改异常
为什么会出现这个异常呢?那是因为迭代器遍历机制,规定迭代器遍历集合的同时,不允许集合自己去增删元素,否则就会出现这个异常。

 使用for方法看,要加入i--才会执行成功

3.1解决方法

怎么解决这个问题呢?不使用集合的删除方法,而是使用迭代器的删除方法,代码如下:
List<String> list = new ArrayList<>();
list.add("王麻子");
list.add("小李子");
list.add("李爱花");
list.add("张全蛋");
list.add("晓李");
list.add("李玉刚");
System.out.println(list); // [王麻子, 小李子, 李爱花, 张全蛋, 晓李, 李玉刚]//需求:找出集合中带"李"字的姓名,并从集合中删除
Iterator<String> it = list.iterator();
while(it.hasNext()){String name = it.next();if(name.contains("李")){//list.remove(name);it.remove(); //当前迭代器指向谁,就删除谁}
}
System.out.println(list);

4、Collection其他使用

4.1、可变参数

public class ParamTest{public static void main(String[] args){//不传递参数,下面的nums长度则为0, 打印元素是[]test();//传递3个参数,下面的nums长度为3,打印元素是[10, 20, 30]test(10,20,30);//传递一个数组,下面数组长度为4,打印元素是[10,20,30,40]int[] arr = new int[]{10,20,30,40}test(arr);}public static void test(int...nums){
//可变参数在方法内部,本质上是一个数组System.out.println(nums.length);System.out.println(Arrays.toString(nums));System.out.println("----------------");}
}

4.2、Collections工具类

Collections 是用来操作Collection 的工具类
public class CollectionsTest{public static void main(String[] args){//1.public static <T> boolean addAll(Collection<? super T> c, T...e)对集合批量添加数据List<String> names = new ArrayList<>();Collections.addAll(names, "张三","王五","李四", "张麻子");System.out.println(names); //2.public static void shuffle(List<?> list):对List集合打乱顺序Collections.shuffle(names);System.out.println(names); //3.public static <T> void short(List<T list): 对List集合排序List<Integer> list = new ArrayList<>();list.add(3);list.add(5);list.add(2);Collections.sort(list);System.out.println(list);}
}
上面我们往集合中存储的元素要么是 Stirng 类型,要么是 Integer 类型,他们本来就有一种自然顺序所以可以直接排序。但是如果我们往List 集合中存储 Student 对象,这个时候想要对 List 集合进行排序自定义比较规则的。指定排序规则有两种方式,如下:
排序方式 1 :让元素实现 Comparable 接口,重写 compareTo 方法
比如现在想要往集合中存储 Studdent 对象,首先需要准备一个 Student 类,实现 Comparable 接口。
public class Student implements Comparable<Student>{private String name;private int age;private double height;//排序时:底层会自动调用此方法,this和o表示需要比较的两个对象@Overridepublic int compareTo(Student o){//需求:按照年龄升序排序//如果返回正数:说明左边对象的年龄>右边对象的年龄//如果返回负数:说明左边对象的年龄<右边对象的年龄,//如果返回0:说明左边对象的年龄和右边对象的年龄相同return this.age - o.age;}//...getter、setter、constructor..
}
然后再使用 Collections.sort(list 集合 ) List 集合排序,如下:
//3.public static <T> void short(List<T list): 对List集合排序
List<Student> students = new ArrayList<>();
students.add(new Student("蜘蛛精",23,169.7));
students.add(new Student("紫霞",22,169.8));
students.add(new Student("紫霞",22,169.8));
students.add(new Student("至尊宝",26,169.5));
/*
原理:sort方法底层会遍历students集合中的每一个元素,采用排序算法,将任意两个元素两两比较;每次比较时,会用一个Student对象调用compareTo方法和另一个Student对象进行比较;根据compareTo方法返回的结果是正数、负数,零来决定谁大,谁小,谁相等,重新排序元素的位置注意:这些都是sort方法底层自动完成的,想要完全理解,必须要懂排序算法才行;
*/
Collections.sort(students);
System.out.println(students);
排序方式 2 :使用调用 sort 方法是,传递比较器
/*
原理:sort方法底层会遍历students集合中的每一个元素,采用排序算法,将任意两个元素两两比较;
每次比较,会将比较的两个元素传递给Comparator比较器对象的compare方法的两个参数o1和o2,
根据compare方法的返回结果是正数,负数,或者0来决定谁大,谁小,谁相等,重新排序元素的位置
注意:这些都是sort方法底层自动完成的,不需要我们完全理解,想要理解它必须要懂排序算法才行.
*/
Collections.sort(students, new Comparator<Student>(){@Overridepublic int compare(Student o1, Student o2){return o1.getAge()-o2.getAge();}
});
System.out.println(students);

相关文章:

Java单列集合[Collection]

目录 1.Collection单列集合 1.1单列集合各集合特点 1.2、Collection集合 1.2.1、Collection方法 1.2.2、Collection遍历方式 1.2.2.1、迭代器遍历集合 1.2.2.2、增强for遍历集合 1.2.2.3、forEach遍历集合&#xff08;JDK8之后&#xff09; 1.2.2.4、遍历案例 1.3、Li…...

【C++重点】lambda表达式是什么

Lambda 表达式是 C11 引入的特性&#xff0c;它允许你定义匿名函数对象&#xff08;即没有名字的函数&#xff09;。Lambda 表达式可以在需要函数对象的地方直接定义函数&#xff0c;常用于 STL 算法和回调机制中。 lambda表达式基本语法 [捕获列表](参数列表) -> 返回类型…...

如何在ONLYOFFICE插件中添加自定义AI提供商:以通义千问和Kimi为例

随着 ONLYOFFICE AI 插件的发布&#xff0c;我们极大地提升了编辑器的默认功能。在ONLYOFFICE&#xff0c;我们致力于提供强大且灵活的解决方案&#xff0c;以满足您的特定需求。其中一项便是能够在 AI 插件中添加自定义提供商。在这篇文章中&#xff0c;我们将展示如何将通义千…...

Java基础-26-多态-认识多态

在Java编程中&#xff0c;多态&#xff08;Polymorphism&#xff09; 是面向对象编程的核心概念之一。通过多态&#xff0c;我们可以编写更加灵活、可扩展的代码。本文将详细介绍什么是多态、如何实现多态&#xff0c;并通过具体的例子来帮助你更好地理解这一重要概念。 一、什…...

Spark,配置hadoop集群1

配置运行任务的历史服务器 1.配置mapred-site.xml 在hadoop的安装目录下&#xff0c;打开mapred-site.xml&#xff0c;并在该文件里面增加如下两条配置。 eg我的是在hadoop199上 <!-- 历史服务器端地址 --> <property><name>mapreduce.jobhistory.address…...

【蓝桥杯算法练习】205. 反转字符串中的字符(含思路 + Python / C++ / Java代码)

【蓝桥杯算法练习】205. 反转字符串中的字符&#xff08;含思路 Python / C / Java代码&#xff09; &#x1f9e9; 题目描述 给定一个字符串 s&#xff0c;请你将字符串中的 英文字母字符反转&#xff0c;但其他 非字母字符保持在原位置&#xff0c;输出处理后的字符串。 …...

FPGA实现4K MIPI视频解码H265压缩网络推流输出,基于IMX317+VCU架构,支持4K60帧,提供工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目我这里已有的 MIPI 编解码方案我这里已有的视频图像编解码方案 3、详细设计方案设计框图FPGA开发板IMX317摄像头MIPI D-PHYMIPI CSI-2 RX Subsystem图像预处理Sensor …...

【Linux】网络概念

目录 网络模型 OSI七层模型 TCP/IP五层(或四层)模型 网络传输 网络传输基本流程 封装与分用 以太网通信&#xff08;局域网传输&#xff09; 跨网络传输 网络模型 OSI七层模型 TCP/IP五层(或四层)模型 网络层和传输层就是操作系统的一部分 网络传输 网络传输基本流程…...

【模拟CMOS集成电路设计】电荷泵(Charge bump)设计与仿真(示例:栅极开关CP+轨到轨输入运放+基于运放CP)

【模拟CMOS集成电路设计】电荷泵&#xff08;Charge bump&#xff09;设计与仿真 0前言1电荷泵1.1 PFD/CP/电容器级联1.2 PFD/CP/电容传递函数 2基本电荷泵(CP)结构2.1“漏极开关”结构2.2“源极开关”结构2.3“栅极开关”结构 3 CP的设计与仿真13.1 P/N电流源失配仿真3.2 电荷…...

minecraft.service 文件配置

minecraft.service 文件配置 # /etc/systemd/system/minecraft.service [Unit] DescriptionMinecraft Fabric Server Afternetwork.target Wantsnetwork-online.target[Service] Usermcfabricuser Groupmcfabricuser WorkingDirectory/minecraft/1.21.1-fabric-server ExecStar…...

Kafka消息丢失全解析!原因、预防与解决方案

作为一名高并发系统开发工程师&#xff0c;在使用消息中间件的过程中&#xff0c;无法避免遇到系统中消息丢失的问题&#xff0c;而Kafka作为主流的消息队列系统&#xff0c;消息丢失问题尤为常见。 在这篇文章中&#xff0c;将深入浅出地分析Kafka消息丢失的各种情况&#xf…...

VS Code 云服务器远程开发完整指南

VS Code Ubuntu 云服务器远程开发完整指南 远程开发是现代开发者的标配之一&#xff0c;特别是在使用云服务器&#xff08;如 Ubuntu&#xff09;进行部署、测试或大项目开发时&#xff0c;利用 VS Code 的 Remote-SSH 插件&#xff0c;可以像本地一样顺滑操作远程服务器。本…...

Linux孤儿进程和僵尸进程

目录 1、孤儿进程 2、僵尸进程 在 Linux 系统中&#xff0c;父子进程关系的生命周期不同&#xff0c;导致会产生两类特殊进程&#xff1a;孤儿进程和僵尸进程。这两类进程在系统资源管理中起着重要作用。 1、孤儿进程 孤儿进程指的是父进程先于子进程结束&#xff0c;导致子…...

【Rtklib入门指南】4. 使用RTKLIB进行载波相位差分定位(RTK)

RTK RTK&#xff08;Real-Time Kinematic&#xff0c;实时动态&#xff09;定位技术是一种高精度的卫星导航技术。相比传统的GPS定位技术&#xff0c;RTK能够在厘米级别的精度范围内提供定位结果。这使得RTK技术在无人机、自动驾驶、工程测绘、农业机械自动化等领域具有广泛应用…...

【SECS】初识SECS协议

【SECS】初识SECS协议 基本知识流和功能函数数量官方文件中缩写标注正常是不是都是主机向设备端?对数据信息中第1字节第1-2位官网介绍 S1F1双向指令说明测试H发起端E发起端 参考资料 基本知识 SECS&#xff08;SEMI Equipment Communications Standard&#xff09;即半导体设…...

【C++项目】从零实现RPC框架「三」:项⽬抽象层实现

🌈 个人主页:Zfox_ 🔥 系列专栏:C++从入门到精通 目录 一:🔥 常⽤的零碎功能接⼝类实现🦋 简单⽇志宏实现🦋 Json 序列化/反序列化🦋 UUID ⽣成二:🔥 项⽬消息类型字段信息定义 🦋 请求字段宏定义🦋 消息类型定义🦋 响应码类型定义🦋 RPC 请求类型定…...

webcam video demo

一个 demo&#xff0c;使用 OpenCV&#xff0c;手动操作 webcam&#xff0c;保持相机打开&#xff0c;防止频繁的 开关损坏摄像头硬件。 这是ROS情景下的一个节点&#xff0c;展示了ROS节点的常见格式。代码很简单&#xff0c;单展示了持续视频流的发布&#xff0c;还展示了基…...

ARM-LDS链接文件

关键字 ALIGN 在链接脚本中&#xff0c;ALIGN关键字&#xff1a;ALIGN(X)中的X表示多少个字节对齐。 在汇编文件中&#xff0c;是伪操作 .align x 实现的&#xff1a;表示2的x次幂个字节对齐&#xff1b; 2.X的取值也是有讲究的&#xff0c;必须是2的整数次幂。例如&#xf…...

相机镜头景深

文章目录 定义影响因素实际应用特殊情况 参考&#xff1a;B站优致谱视觉 定义 景深是指在摄影机镜头或其他成像器前沿着能够取得清晰图像的成像器轴线所测定的物体距离范围。简单来说&#xff0c;就是在一张照片中&#xff0c;从前景到背景&#xff0c;能够保持清晰锐利的区域…...

Linux基础入门:从零开始掌握Linux命令行操作

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 &#x1f388;有没有觉得电影里的黑客&#x1f412;酷毙了&#xff1f;他们只用键盘⌨就能搞定一切。今天&#xff0c;毛毛张要带你们体验这种快感&#x1f600;&…...

C++第13届蓝桥杯省b组习题笔记

1.九进制转十进制 九进制正整数 (2022)9转换成十进制等于多少&#xff1f; 第一位乘9的0次方&#xff0c;第二位乘9的1次方&#xff0c;第三位乘9的二次方以此类推 #include <iostream> using namespace std;int main() {// 请在此输入您的代码int t2022;int res0;int c…...

探索 Gaggol:理解 10^^^100 的宇宙级常数

一、常数概述&#xff1a; Gaggol 是一个极其巨大的数学常数&#xff0c;其数值表示为 10^^^100。这个常数是通过对数字 10 进行超递归幂运算得到的结果。 二、Gaggol 的定义&#xff1a; Gaggol 被定义为 10 的超多层超递归幂&#xff0c;即 10 被连续地提升到自身幂的层次达…...

python-leetcode 61.N皇后

题目&#xff1a; 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解…...

Centos8 系統Lnmp服務器環境搭建

Centos8 系統Lnmp服務器環境搭建 服務器環境 Centos8 [rootcentos8 ~]# uname -a Linux centos8 4.18.0-348.el8.x86_64 #1 SMP Tue Oct 19 15:14:17 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux# 更新軟件包列表 rootdebian:~# dnf update安裝信息 PHP 版本8.2.27 https://ww…...

产教融合|暴雨技术专家执裁江苏省职业院校技能大赛

3月28-30日&#xff0c;由江苏省教育厅、省发改委、省工信厅等15家单位主办的2025年江苏省职业院校技能大赛网络系统管理赛项如期举办。此次赛事吸引了全省52支参赛队伍、156名选手踊跃参与&#xff0c;参赛人数再创新高。 暴雨信息技术专家李明宇作为此赛项的往届省赛冠军&am…...

BUUCTF-web刷题篇(6)

15.PHP 知识点&#xff1a; ①__wakeup()//将在反序列化之后立即调用&#xff08;当反序列化时变量个数与实际不符是会绕过&#xff09;我们可以通过一个cve来绕过:CVE-2016-7124。将Object中表示数量的字段改成比实际字段大的值即可绕过wakeup函数。条件&#xff1a;PHP5<…...

AIP-203 域行为文档

编号203原文链接AIP-203: Field behavior documentation状态批准创建日期2018-07-17更新日期2018-07-17 在定义protocol buffer中的域时&#xff0c;按惯例要向用户解释域行为的某些方面&#xff08;例如域是必需的还是可选的&#xff09;。此外&#xff0c;让其他工具理解域行…...

在 Cloud Run 上使用 Gemini API 构建聊天应用

李升伟 编译 (&#x1f3a8; 封面由 Gemini 中的 Imagen 3 生成&#xff01;) 欢迎来到我的谷歌AI工具构建系列博客&#xff01;本文将带您创建一个由Gemini驱动并托管在Cloud Run上的简易聊天应用。如果您正在探索大语言模型或希望将AI集成到网页应用中&#xff0c;那么您来…...

周总结aa

上周学习了Java中有关字符串的内容&#xff0c;与其有关的类和方法 学习了static表示静态的相关方法和类的使用。 学习了继承(extends) 多态&#xff08;有继承关系&#xff0c;有父类引用指向子类对象&#xff09; 有关包的知识&#xff0c;final关键字的使用&#xff0c;及有…...

31天Python入门——第17天:初识面向对象

你好&#xff0c;我是安然无虞。 文章目录 面向对象编程1. 什么是面向对象2. 类(class)3. 类的实例关于self 4. 对象的初始化5. __str__6. 类之间的关系继承关系组合关系 7. 补充练习 面向对象编程 1. 什么是面向对象 面向对象编程是一种编程思想,它将现实世界的概念和关系映…...