Java学习笔记 集合的使用

news2024/10/7 20:32:01

在实际的项目中开发过程中,会有很多的对象,如何高效、方便的管理这些对象,是影响程序性能与可维护性的重要环节。在Java语言中为这个问题提供了一套完美的解决方案,也就是接下来要介绍的集合框架。

1.1 集合框架的结构

在这里插入图片描述
在这里插入图片描述
从Collection接口 继承而来的一般被称为聚焦(有时也被宽泛的称为集合),从Map接口继承来的一般被称为映射。

在Set和Map接口中,都有一个继承自他们的SortedXXX子接口(XXX = Set/Map)

1.2 列表

1.2.1 List(列表)接口

List接口继承自Collection接口,代表列表的功能(角色),其中的元素可以按索引的顺序访问,所以也可以称为有索引的Collection。实现该接口的类均属于Ordered
类型,具有列表的功能,其元素顺序均是按照添加(索引)的先后进行排列的

List接口的常用方法
(略)

与数组一样,列表中的索引是从0开始的,实现了List接口的类也可以被看做可变长度的数组来使用。
List接口中的方法很注重索引。如果开发人员需要对其中每个元素的插入位置进行精准的控制,并且需要根据元素的整数索引访问元素,或搜索列表中的元素,则可以使用实现了该类的接口类。

1.2.2 数组实现列表

ArrayList,是List接口最常用的实现之一。可以向其中添加包括null值在内的所有对象引用型的元素。甚至该对象引用自己也可以作为其中的元素。这样可以方便的搭建一个树状结构的集合。

该类内部类实际上是依赖数组实现的,因此对元素进行随机访问的性能很好,但如果进行大量的插入、删除操作,该类性能很差,

ArrayList中,功能方法大都实现自List接口。

package list;

import java.util.ArrayList;

//一个使用ArrayList的例子
public class Sample1 {
public static void main(String[] args) {

	//创建列表ArrayList对象
	ArrayList al = new ArrayList(); 
	
	//初始化ArrayList中的元素
	for(int i = 0;i<50;i++) {
		al.add(String.valueOf(i));
	}
	//对arrlist进行操作
	for(int i = 60;i<75;i++) {
		al.set(i-45, String.valueOf(i));
	}
	
	//打印ArrayList列表里的内容
	System.out.println("这是ArrayList操作后的结果:");
	System.out.println(al);
	//取出指定元素并进行处理
	Object o = al.get(22);
	String s = (String)o;
	System.out.println("索引为22的元素长度为:"+s.length());

}
}

在这里插入图片描述

  • 将ArrayList中从索引15开始之后长度为15区间内的元素依次设置为数字60~74的字符串,
  • 头文件:java.util.*
  • 在没有使用泛型的情况下,无论放进集合的是什么元素,取出的都是Object类型的引用,
    ArrayList中并不真正存放对象,而只是存放对象的引用,所有集合框架中的类都如此

1.3 链接实现列表

指LinkedList类,功能与ArrayList类相同,都是列表List的实现。由于其内部是依赖双链表来实现的,因此具有很好的插入、删除性能。但随机访问元素相对较差。适合用在插入、删除多,元素随机访问少的场合。

package list;

import java.util.LinkedList;

public class Sample2 {

	public static void main(String[] args) {

		//创建列表LinkedList对象
		LinkedList ll = new LinkedList();
		
		//初始化LinkedList对象
		for(int i = 0;i<50;i++) {
			ll.add(String.valueOf(i));
		}
		//对LinkedList进行插入操作
		for(int i = 15;i<30;i++) {
			ll.add(i,String.valueOf(30-i+15));
		}
		//打印LinkedList列表
		System.out.println("这是LinkedList操作后的结果");
		System.out.println(ll);
	}

}

在这里插入图片描述
在LinkedList索引为15的地方插入15个元素,其中内容为30-16的字符串。

1.3.1 依赖性倒置原理

依赖项倒置原理:依赖应尽量在抽象层进行,避免在具体层进行。
在实际开发中的含义就是应该尽量使用接口类型的引用,避免使用具体类型的引用。

package list;

import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

public class MyClass {

		//声明具体类类型的引用
		public LinkedList firstList = new LinkedList();
	
		//声明具体类类型入口参数的方法
		public void printLinkedList(LinkedList ll) {
			System.out.println(ll);
		}
		//声明接口类型的引用
		public List lastList = new Vector();
		//声明接口类型入口参数的方法
		public void printAllKindsOfList(List l) {
			System.out.println(l);
		}

}

-firstList是具体类类型的引用,在未来如果需要改变为其他类型,则会严重影响依赖他的代码。而LastList是接口类型的引用,在未来如果需要,可以指向任何实现了该接口的类的对象,对外面依赖它的代码没有任何影响。
-printLinkedList()方法的入口参数书具体类型的,只能接收一种类型的参数。而printAllKindsOfList()方法的入口参数是接口类型的,可接收任何实现了该接口类型的引用。灵活性更大。

1.3.2 将数组转换成列表

使用Java类库中Java.util.Arrays类的静态方法asList()

package list;

import java.util.Arrays;
import java.util.List;

public class Sample3 {

	public static void main(String[] args) {
		//创建一维字符串数组对象
		String[] s = {"tom","jerry","lucy","jc"};
		//将一维字符串数组转换为列表
		List l = Arrays.asList(s);
		System.out.println("这是将字符串数组转化为列表后的结果"+l);
	}
}

在这里插入图片描述

1.4 集合

Set接口及其子接口与实现了这些接口的类都可以被称为是集合(Set)

1.4.1 Set接口

Set接口继承自Collection接口,和同样继承自Collection接口的List接口的不同之处在于:

  1. List接口按顺序将对象引用添加进去,对引用指向的对象没有特别的要求,Set接口不允许有重复的元素。
  2. List接口中的元素有顺序,就是添加的顺序,set接口中元素没有顺序,可以按照顺义顺序进行存放。

1.4.2 HashSet接口

HashSet类是Set接口最常用的实现之一。实际上,HashSet存储对象引用是按照哈希策略来实现的。另外,可以向HashSet中添加null值,但只能添加一次。

package list;

import java.util.HashSet;

public class Sample4 {

	public static void main(String[] args) {
		
		HashSet hs = new HashSet();
		
		hs.add(5);
		hs.add(1);
		hs.add(3);
		hs.add(2);
		hs.add(4);
		//移除5
		hs.remove(5);
		//添加1
		hs.add(1);
		//添加null
		hs.add(null);
		//打印
		System.out.println("这时HashSet操作后的结果");
		System.out.println(hs);
	}

}

在这里插入图片描述

  • HashSet对象并不保证元素的存储数据,相同的元素在Hash对象中只能出现一次,同时HashSet对象中允许存放null值。

1.4.3 equals()与Hashcode()方法重写的作用。

package list;

import java.util.HashSet;

public class Sample5 {

	public static void main(String[] args) {
		//创建空HashSet对象。
		HashSet hs = new HashSet();
		
		//向空HashSet中添加名字为tom的Student对象
		System.out.println("=============================");
		System.out.println("向空HashSet中添加名字为tom的元素");
		hs.add(new Student("tom"));
		System.out.println("此时HashSet里的元素为");
		System.out.println(hs);
		System.out.println("=============================");	
	
		//向空HashSet中添加名字为wjc的Student对象
		System.out.println("=============================");
		System.out.println("向空HashSet中添加名字为wjc的元素");
		hs.add(new Student("wjc"));
		System.out.println("此时HashSet里的元素为");
		System.out.println(hs);
		System.out.println("=============================");	
	
		//向空HashSet中添加名字为wyf的Student对象
		System.out.println("=============================");
		System.out.println("向空HashSet中添加名字为wyf的元素");
		hs.add(new Student("wyf"));
		System.out.println("此时HashSet里的元素为");
		System.out.println(hs);
		System.out.println("=============================");	
		
		//向空HashSet中再次添加名字为wjc的Student对象
		System.out.println("=============================");
		System.out.println("向空HashSet中再次添加名字为wjc的元素");
		hs.add(new Student("wjc"));
		System.out.println("此时HashSet里的元素为");
		System.out.println(hs);
		System.out.println("=============================");	
	}

}

class Student{
	//学生的姓名成员 
	private String name;
	public Student(){}
	public Student(String name) {
		this.name = name;
	}
	//重写toString()方法
	public String toString() {
		//返回属性值的字符串
		return "["+this.name+"]";
	}
	//重写equals()方法
	public boolean equals(Object o) {
		//打印显示调用信息
		System.out.println("调用了"+this.name+"的equals方法,与"+((Student)o).name+"比");
		//测试是否指向同一个对象
		if(this==o) {return true;}
		//测试引用o是否为null
		if(o==null) {return false;}
		//测试o是否同Student的instanceof测试
		if(!(o instanceof Student)) {return false;}
		//将引用类型进行强制转换
		Student s = (Student)o;
		//测试内容是否相同
		if(this.name.equals(s.name)) {return true;}
		else {return false;}
	}
	//重写hashcode()方法
	public int hashCode() {
		//计算哈希码
		int hc = 7*this.name.charAt(0);
		//打印显示调用信息
		System.out.println("调用了"+this.name+"的hashCode方法,哈希码为"+hc);
		return hc;
	}
}

总结
因为采用的存储策略是哈希的,所以每次添加元素,都必须调用hashcode方法;由于有了hashCode与equals方法的约定,不再一只哈希桶中的元素equals一定不会返回true,这就避免了大量无谓的equals比较,提高了执行效率。
在这里插入图片描述

1.4.4 LinkedHashSet

LinkedHashSet类是Ordered的,其采用双链表实现,元素在其中的存储有固定的顺序,也就是插入元素的顺序。其他方法的特性与HashSet类均相同,也就是Set接口。

package list;

import java.util.LinkedHashSet;

public class Sample6 {

       public static void main(String[] args) {

           LinkedHashSet linkedHashSet = new LinkedHashSet();
           linkedHashSet.add(String.valueOf(5));//OK
           linkedHashSet.add(String.valueOf(1));//OK
           linkedHashSet.add(String.valueOf(3));//OK
           linkedHashSet.add(String.valueOf(2));
           linkedHashSet.add(String.valueOf(4));//OK

           linkedHashSet.remove(String.valueOf(5));
           linkedHashSet.add(null);
           
           System.out.println("linkedHashSet=" + linkedHashSet);

       }

}

在这里插入图片描述
元素输出顺序与linkedHashSet中插入元素的先后顺序完全相同

1.5 映射

1.5.1 MAP接口

Map也被称为键/值集合,因为在实现了该接口的集合元素中都是成对出现的,一个被称为键,一个被称为值。键和值都是对象。键对象用来在Map中唯一标识一个值对象。键对象在Map中不能重复出现。

1.5.2 HashMap类

HashMap类是Map接口最常用实现之一。该类通过对键计算哈希码来决定值的存储,不保证键的存储数据。键值允许为null,但只能出现一次。

package list;

import java.util.HashMap;

public class Sample7 {

	public static void main(String[] args) {
		//创建HashMap对象。
		HashMap hm = new HashMap();

		hm.put(Integer.valueOf(97005), "tom");
		hm.put(Integer.valueOf(97003), "Jerry");
		hm.put(Integer.valueOf(97004), "Lucy");
		hm.put(Integer.valueOf(97001), "Smith");
		hm.put(Integer.valueOf(97002), "JC");
		System.out.println("这是HasnMap操作前的结果");
		System.out.println(hm);
		hm.remove(Integer.valueOf(97005));//删除
		hm.put(Integer.valueOf(97002), "David");//替换
		//打印
		System.out.println("这是HasnMap操作后的结果");
		System.out.println(hm);
		//取出指定键对应的值
		Object o = hm.get(97003);
		String s = (String)o;
		System.out.println("键97003对应的值为"+s+"长度为"+s.length());
	}

}

在这里插入图片描述

1.5.3 HashTable类

早起Java遗留下来的,功能特性与HashMap基本上是想听的,不同之处是该类对元素操作的方法是同步方法,在运行的时候可能会损失一些性能。因此,一般使用HashMap

package list;

import java.util.HashMap;
import java.util.Hashtable;

public class Sample8 {

   public static void main(String[] args) {
   	//创建HashMap对象。
   	Hashtable ht = new Hashtable();

   	ht.put(Integer.valueOf(97005), "tom");
   	ht.put(Integer.valueOf(97003), "Jerry");
   	ht.put(Integer.valueOf(97004), "Lucy");
   	ht.put(Integer.valueOf(97001), "Smith");
   	ht.put(Integer.valueOf(97002), "JC");
   	System.out.println("这是Hasntable操作前的结果");
   	System.out.println(ht);
   	
   	//判断HashTable对象中是否存在键位97001的值
   	boolean b = ht.containsKey(97001);
   	System.out.println((b)?"存在":"不存在");
   	
   	ht.put(Integer.valueOf(97002), "David");//替换
   	//打印
   	System.out.println("这是Hasntable操作后的结果");
   	System.out.println(ht);
   	//取出指定键对应的值
   	Object o = ht.get(97003);
   	String s = (String)o;
   	System.out.println("键97003对应的值为"+s+"长度为"+s.length());
   }
}

在这里插入图片描述

1.5.4 LinkedHashMap类

LinkedHashMap类是通过双链表的方式实现的Map,这一点与LinkedHashSet类相同。LinkedHashMap类的基本功能与HashMap基本相同。插入/删除效率略差,遍历效率略高。

package list;

import java.util.LinkedHashMap;

public class Sample9 {

	public static void main(String[] args) {
		//创建LinkedHashMap对象
		LinkedHashMap lhm = new LinkedHashMap();
		lhm.put(Integer.valueOf(97005), "tom");
		lhm.put(Integer.valueOf(97003), "Jerry");
		lhm.put(Integer.valueOf(97004), "Lucy");
		System.out.println("这是LinkedHashMap操作前的结果");
		System.out.println(lhm);

		lhm.put(Integer.valueOf(97003), "David");//替换
		
		//对象中是否存在键位97001的值
		boolean b = lhm.containsValue("Jerry");
		System.out.println((b)?"存在":"不存在");
		
		System.out.println("这是LinkedHashMap操作后的结果");
		System.out.println(lhm);
		
	}

}

在这里插入图片描述

1.6 集合元素的常用操作

在实际开发过程中,经常要对集合中的元素进行排序、搜索等操作,为了简化开发,java中提供了一个java.util.Collections类。
Collections是一个工具类。提供的功能方法是静态方法。

1.6.1 元素排序

sort() 方法主要有如下两种重载形式。


void sort(List list):根据元素的自然顺序对集合中的元素进行升序排序。
void sort(List list,Comparator comparator):按 comparator 参数指定的排序方式对集合中的元素进行排序。
package list;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Sample10 {
	public static void main(String[] args) {
		//创建ArrayList对象
		ArrayList al = new ArrayList();
		//为ArrayList初始化随机整数
		for(int i = 0 ;i<50;i++) {
			al.add(Integer.valueOf((int)(Math.random()*100)));
		}
		System.out.println("这是ArrayList排序前的结果");
		System.out.println(al);
		Collections.sort(al);
		System.out.println("这是ArrayList排序后的结果");
		System.out.println(al);
		//使用比较器进行排序
		Collections.sort(al,new MyComparator());
		System.out.println("这是使用比较器排序之后ArrayList中的元素");
		System.out.println(al);
	}
}
class MyComparator implements Comparator{

	@Override
	public int compare(Object o1, Object o2) {
		// TODO Auto-generated method stub
		Integer i1 = (Integer)o1;
		Integer i2 = (Integer)o2;
		return i2.intValue() - i1.intValue();
	}	
}

在这里插入图片描述

1.6.2 搜索特定的元素

package list;

import java.util.ArrayList;
import java.util.Collections;

public class Sample11 {
	public static void main(String[] args) {
		ArrayList al = new ArrayList();
		//为ArrayList初始化随机整数
		for(int i = 0 ;i<50;i++) {
			al.add(Integer.valueOf((int)(Math.random()*100)));
		}
		Collections.sort(al);
		//查找指定元素
		int index = Collections.binarySearch(al, Integer.valueOf(20));
		if(index<0) {
			System.out.println("没有找到打印的结果");
		}else {
			System.out.println("找到了元素,索引是"+index);
			for(int i = 0;i<al.size();i++) {
				if(i==index) {
					System.out.print("["+al.get(i)+"]");
				}else {
					System.out.print(al.get(i)+",");
				}
			}
		}
	}
}

在这里插入图片描述

1.7 技术解惑

1.7.1 ArrayList为什么是线程不安全的

ArrayList在添加一个元素的时候,可能会通过两步来完成
(1)在Items[Size]的位置存放此元素。
(2) 增大size的值。
在单线程情况下,如果Size = 0,那么添加一个元素后,此元素位置在0,而且size = 1
而在多线程运行的情况下,比如有两个线程,线程A先将元素存放在位置0,但此时CPU调度线程A,线程A暂停运行,线程B得到运行的机会。线程B也向此ArrayList添加元素。因为此时Size仍然等于0(添加一个元素需要两个步骤,而线程A仅仅完成了第一步),所以线程B也将元素存放在位置0.然后线程A和线程B都继续运行,都增加size的值。此时,ArrayList中元素只有一个存放在位置0,但Size却等于2.这就是线程不安全、

1.7.2 使用LinkedList来模拟一个堆栈或者队列数据结构

堆栈:先进后出 ,First In Lat Out,FILO
队列:先进先出 First In First Out,FIFO

public class QUEUE{
	private LinkedList link;
	public Queue(){
	link = new LinkedList();
}
public void push(Object obj){
link.addLast(obj);
}
public Object pop(){
	return link.removeFirst();
}
public boolean isEmpty(){
return link.isEmpty();
}


}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是 Batch Normalization 批标准化和全连接层

Batch Normalization 神经元在经过激活函数之后会处于饱和状态&#xff0c;无论后续怎么变化都不会再起作用。 每一层都会进行batch normalization的处理&#xff01; without normalization 会导致数据分布再饱和区 全连接层&#xff1a; 全连接层(fully connected layers&a…

DPDK基础组件一(mbuf、ring、pktmbuf_pool)

一、rte_mbuf 此部分转自:https://zhuanlan.zhihu.com/p/616314276 1.mbuf结构 mbuf是报文中的描素的结构体,是整个转发过程中最核心的数据结构之一。主要针对于mbuf的常用API与基本原理做一个简单的介绍。 mbuf:报文内存存储结构,存储在mempool中mempool:使用环形缓冲…

【kubernetes】k8s集群中的ingress(对外服务)规则详解

目录 一、Ingress 简介 1.1service的作用 1.2外部访问方案 (四种&#xff09;&#x1f339;&#x1f339;&#x1f339; 部署externalIPs 1.3Ingress 是什么 二、Ingress 组成&#x1f339;&#x1f339;&#x1f339; 三、Ingress 工作原理&#x1f431;&#x1f…

一维时间序列信号的小波时间散射变换(MATLAB 2021)

小波散射变换的目的在于获取第一层次的特征信息&#xff0c;即免疫平移、轻微形变的信息。而低通的滤波器能够获取输入信号的概貌&#xff0c;获取反映其整体大尺度特征的信息&#xff0c;以图像为例&#xff0c;由低通滤波器选取的信号对于图像的平移、伸缩、旋转等局部变化有…

【QT5】<总览二> QT信号槽、对象树及样式表

文章目录 前言 一、QT信号与槽 1. 信号槽连接模型 2. 信号槽介绍 3. 自定义信号槽 二、不使用UI文件编程 三、QT的对象树 四、添加资源文件 五、样式表的使用 六、QSS文件的使用 前言 承接【QT5】&#xff1c;总览一&#xff1e; QT环境搭建、快捷键及编程规范。若存…

计算机发展史 | 从起源到现代技术的演进

computer | Evolution from origins to modern technology 今天没有参考资料哈哈 PPT&#xff1a;&#xff08;评论区&#xff1f;&#xff09; 早期计算工具 算盘 -算盘是一种手动操作的计算辅助工具&#xff0c;起源于中国&#xff0c;迄今已有2600多年的历史&#xff0c;是…

告别鼠标:蓝牙无线安卓模拟鼠标,绘图板,手写板操作电脑PC端,卡卡罗特也说好,儿童节快乐

家人们&#xff0c;上链接了&#xff1a;https://download.csdn.net/download/jasonhongcn/89387887 横屏模式&#xff1a; 竖屏模式&#xff1a; 操作说明&#xff1a; 1. 手势滑动模拟鼠标移动 2. 界面如果有滚动条&#xff0c;右手指按紧&#xff0c;通过左手指移动实现…

智慧医疗新纪元:可视化医保管理引领未来

在数字化浪潮席卷全球的今天&#xff0c;我们的生活正在经历前所未有的变革。其中&#xff0c;智慧医保可视化管理系统就像一股清新的风&#xff0c;为医疗保障领域带来了全新的活力与可能。 想象一下&#xff0c;在繁忙的医院里&#xff0c;患者和家属不再需要为了查询医保信息…

适合航天航空的国产FTP替代软件

在宇宙探索的旅程中&#xff0c;航空和航天领域总是站在科技的最前沿&#xff0c;对数据传输的要求特别高。随着信息量急剧增加和安全威胁的复杂化&#xff0c;传统的FTP软件已经不能满足这个高端领域的需要了。因此&#xff0c;找到一款适合航空和航天领域的FTP替代软件&#…

SQLServer 查询指定数据库名和表名及表结构等

查询当前数据库中所有表名&#xff0c;不用指定数据库&#xff0c;选中某数据库直接执行SQL就好 -- U:所有用户表名; S:所有系统表名;V:所有视图表名 SELECT name FROM sysobjects WHERE xtypeU OR xtypeS OR xtypeV 查询指定数据库数据库中所有表名&#xff0c; SELECT TAB…

ad18学习笔记21:焊盘设置Paste Mask Expansion(锡膏层延伸)

在pcb上放置焊盘的时候&#xff0c;可以对焊盘进行设置&#xff0c;可以用默认的规则&#xff0c;可以用自定义的规则&#xff0c;网上很少看到自定义的规则怎么用。 参考了官方的说明文档&#xff0c;我只是稍微补充了一下 paste mask与solder mask有哪些区别_paste mask与s…

【30天精通Prometheus:一站式监控实战指南】第10天:blackbox_exporter从入门到实战:安装、配置详解与生产环境搭建指南,超详细

亲爱的读者们&#x1f44b;   欢迎加入【30天精通Prometheus】专栏&#xff01;&#x1f4da; 在这里&#xff0c;我们将探索Prometheus的强大功能&#xff0c;并将其应用于实际监控中。这个专栏都将为你提供宝贵的实战经验。&#x1f680;   Prometheus是云原生和DevOps的…

isp效果库相关参数——镜像翻转

前言 之前一直比较忙着接触新工作内容&#xff0c;所以有一段搁置期&#xff0c;但是工作中的知识点还是有一直记录的&#xff0c;只是没空发出来&#xff0c;毕竟需要先熟悉才能总结内容&#xff0c;接下来的几天会连着发布 不同的产品数据手册有着不同的叫法但是统一的意思离…

怎么实现车间生产设备数据文件比传统FTP的精准快速管控?

在现代制造业中&#xff0c;数据管理的重要性日益凸显。车间生产设备产生的数据文件需要被精确、快速地管控&#xff0c;以确保生产效率和产品质量。传统上&#xff0c;文件传输协议&#xff08;FTP&#xff09;被广泛用于数据传输&#xff0c;但它存在一些明显的局限性。 传统…

三十七、openlayers官网示例Earthquakes Heatmap解析——在地图上加载热力图

官网demo地址&#xff1a; Earthquakes Heatmap 这篇主要介绍了热力图HeatmapLayer HeatmapLayer 是一个用于在地图上显示热力图的图层类型&#xff0c;通常用于表示地理数据中的密度或强度。例如&#xff0c;它可以用来显示地震、人口密度或其他空间数据的热点区域。在这个示…

2024050302-重学 Java 设计模式《实战享元模式》

重学 Java 设计模式&#xff1a;实战享元模式「基于Redis秒杀&#xff0c;提供活动与库存信息查询场景」 一、前言 程序员&#x1f468;‍&#x1f4bb;‍的上下文是什么&#xff1f; 很多时候一大部分编程开发的人员都只是关注于功能的实现&#xff0c;只要自己把这部分需求…

flutter as连接网易模拟器

网易模拟器下载 Mac 使用MuMu模拟器调试 Flutter开发 Android Studio 安装第三方模拟器—网易MuMu Mac 安卓Studio使用外部模拟器 Mac电脑&#xff1a;Android Studio 连接 MUMU 网易模拟器 Mac 上 Android Studio 链接网易 MuMu 模拟器调试 在 .zshrc 中设置 adb 二进制文…

计算机毕业设计 | 基于node(Koa)+vue 高校宿舍管理系统 宿舍可视化(附源码)

1&#xff0c;绪论 1.1 项目背景 随着科技的发展&#xff0c;智能化管理越来越重要。大学生在宿舍的时间超过了1/3&#xff0c;因此良好的宿舍管理对学生的生活和学习极为关键。学生宿舍管理系统能够合理安排新生分配宿舍&#xff0c;不浪费公共资源&#xff0c;减轻学校管理…

VBA excel 表格将多行拆分成多个表格或 文件 或者合并 多个表格

excel 表格 拆分 合并 拆分工作表按行拆分为工作表工作表按行拆分为工作薄 合并操作步骤 拆分 为了将Excel中的数万行数据拆分成多个个每个固定行数的独立工作表&#xff0c;并且保留每个工作表的表头&#xff0c;你可以使用以下VBA脚本。这个脚本会复制表头到每个新的工作表&…

opencv进阶 ——(十)图像处理之基于dlib人脸检测与识别

Dlib是一个功能丰富的C库&#xff0c;设计用于构建复杂的软件系统&#xff0c;尤其在机器学习、计算机视觉和数值计算等领域有着广泛的应用。以下是对Dlib的简要介绍&#xff1a; 特性&#xff1a; 机器学习算法&#xff1a;Dlib包含了各种机器学习算法&#xff0c;如支持向量机…