java -数据结构,List相关基础知识,ArrayList的基本使用,泛型的简单、包装类介绍
一、 预备知识-泛型(Generic)
1.1、泛型的引入
比如:我们实现一个简单的顺序表
class MyArrayList{public int[] elem;public int usedSize;public MyArrayList(){this.elem = new int[10];}public void add(int key){this.elem[usedSize] = key;usedSize++;}public int getPos(int pos){return this.elem[pos];}
}
问题:此时我么发现我们实现的顺序表,只能保存 int 类型的元素,如果现在需要保存 指向 Person 类型对象的引用的顺序表,请问应该如何解决?如果又需要保存指向 Book 对象类型的引用呢?
泛型的意义
1、当我们指定数据类型之后,它会在编译器编译的时候,就帮你检查存储的数据类型是否匹配。自动对数据类型进行检查。
2、在我们获取元素的时候,发现数据类型不匹配,此时就会自动的将类型转换成相同类的数据。自动对类型进行强转类型转换。
下面顺序表的写法是不对的,只是为了暂时的用起来
class MyArrayList<E>{public E[] elem;public int usedSize;public MyArrayList(){this.elem = (E[])new Object[10];}public void add(E key){this.elem[usedSize] = key;usedSize++;}public E getPos(int pos){return this.elem[pos];}
}
面试问题:泛型是怎么编译的?
1.泛型是编译期的一种机制(擦除机制)。
擦除机制:它会把尖括号这些内容擦除掉,也就说程序运行的时候,就没有这些东西了。所以说程序运行起来,再去获取它的类型是不可能的,因为都被擦掉了。
然后我们再来看一下细节
1.2、泛型的总结
- 泛型是为了解决某些容器、算法等代码的通用性而引入,并且能在编译期间做类型检查。
- 泛型利用的是 Object 是所有类的祖先类,并且父类的引用可以指向子类对象的特定而工作。
- 泛型是一种编译期间的机制,即 MyArrayList< Person > 和 MyArrayList< Book > 在运行期间是一个类型。
- 泛型是 java 中的一种合法语法,标志就是尖括号 <>
二、预备知识-包装类(Wrapper Class)
Object 引用可以指向任意类型的对象,但有例外出现了,8 种基本数据类型不是对象,那岂不是刚才的泛型机制要
失效了?
实际上也确实如此,为了解决这个问题,java 引入了一类特殊的类,即这 8 种基本数据类型的包装类,在使用过程
中,会将类似 int 这样的值包装到一个对象中去。
2.1、基本数据类型和包装类直接的对应关系
基本就是类型的首字母大写,除了 Integer 和 Character
2.2、包装类的使用,装箱(boxing)和拆箱(unboxing)
例如:此时我们将一个字符串类型的数据转换成int类型的数据
public static void main(String[] args) {String str = "123";int b = Integer.valueOf(str);System.out.println(b + 11);}
什么是装包和拆包
- 装箱,装包: 就是将基本数据类型的数据转换成包装类类型 的数据
- 拆箱,拆包:就是将包装类类型的数据转换成基本数据类型的数据
阿里面试题,和装包和拆包有关
下面执行结果为什么会不相等???
public static void main(String[] args) {Integer a = 129;Integer b = 129;System.out.println("是否相等: " + (a == b));}
为什么???
三、List的使用
3.1、ArrayList 和 顺序表
List是一个接口,不能实例化,但是可以实例一个就提的对象,也可以通过具体的类来实例具体的对象
public static void main(String[] args) {List<String> list = new ArrayList<>();ArrayList<String> arrayList = new ArrayList<>();}
下面的这张图是ArrayList实现的接口和继承的抽象类,但是这张图并不具体
下面这张图才是ArrayList具体实现的接口和类
【说明】
- ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问
- ArrayList实现了Cloneable接口,表明ArrayList是可以clone的
- ArrayList实现了Serializable接口,表明ArrayList是支持序列化的
- 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList
- ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表
3.2、ArrayList 的构造方法
在只用java中的类库时,一定要先看一下类库中的构造方法
public static void main(String[] args) {//不带参数的构造方法,默认大小为0List<String> list1 = new ArrayList<>();//带一个参数的构造方法,大小为10List<String> list2 = new ArrayList<>(10);//将list2作为参数传递,但是list2和list3里面存储的数据类型必须一致List<String> list3 = new ArrayList<>(list2);}
ArrAyList的三种打印方式
1. 直接打印
public static void main(String[] args) {List<String> list1 = new ArrayList<>();list1.add("hello");list1.add("word");list1.add("!!!");System.out.println(list1);}
2. 使用for和for-each循环打印
ArrayList本质上是一个数组,所以可以使用for循环打印,当然也可以使用for-each打印
public static void main(String[] args) {List<String> list1 = new ArrayList<>();list1.add("hello");list1.add("word");list1.add("!!!");for (String str : list1) {System.out.println(str + " ");}}
3. 迭代器打印
public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("123");list.add("hello");list.add("baidu");Iterator<String> iterator = list.iterator();while(iterator.hasNext()){System.out.println(iterator.next() + " ");}}
4、用于List相关的迭代器打印
List<String> list = new ArrayList<String>();list.add("123");list.add("hello");list.add("baidu");ListIterator<String> it = list.listIterator();while (it.hasNext()){System.out.println(it.next() + " ");}
3.3、ArrayList的常用方法
3.3.1、boolean add(E e) - 添加元素
public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("123");list.add("hello");list.add("baidu");System.out.println(list);}
3.3.2、void add(int index, E element) - 在index位置添加元素E
public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("123");list.add("hello");list.add("baidu");list.add(1,"++++");System.out.println(list);}
3.3.3、boolean addAll(Collection<? extends E> c) - 尾插对象e(e是和ArrayList一样的对象)
相当于在顺序表后面在插入一个顺序表
public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("123");list.add("hello");list.add("baidu");List<String> list1 = new ArrayList<String>();list1.add("*****");list1.add("888");list.addAll(list1);System.out.println(list);}
3.3.4、E remove(int index) - 删除index位置的元素
public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("123");list.add("hello");list.add("baidu");System.out.println(list);list.remove(1);System.out.println(list);}
3.3.5、boolean remove(Object o) - 删除第一次遇见的元素
public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("a");list.add("b");list.add("b");list.add("c");boolean b = list.remove("b");System.out.println(list);}
3.3.6、E get(int index) - 获取index位置的元素
public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("a");list.add("b");list.add("b");list.add("c");String str = list.get(2);System.out.println(str);System.out.println(list);}
3.3.7、E set(int index, E element) - 将index位置的元素设置成element
public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("a");list.add("b");list.add("b");list.add("c");String str = list.set(2,"***");System.out.println(str);System.out.println(list);}
3.3.8、void clear() - 清空ArrayList
public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("a");list.add("b");list.add("b");list.add("c");System.out.println(list);list.clear();System.out.println(list);}
3.3.9、boolean contains(Object o) - 判断一个元素是否存在
public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("a");list.add("b");list.add("b");list.add("c");boolean ret = list.contains("b");System.out.println(ret);System.out.println(list);}
3.3.10、int indexOf(Object o) - 返回第一个o 的下表
public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("a");list.add("b");list.add("b");list.add("b");list.add("c");int ret = list.indexOf("b");System.out.println(ret);System.out.println(list);}
3.3.11、int lastIndexOf(Object o) - 返回最后一个o 的下表
public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("a");list.add("b");list.add("b");list.add("b");list.add("c");int ret = list.lastIndexOf("b");System.out.println(ret);System.out.println(list);}
3.3.11、List subList(int fromIndex, int toIndex) - 截取部分list
public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("a");list.add("b");list.add("A");list.add("M");list.add("c");List<String> sub = list.subList(1,3);System.out.println(sub);}
在截取的时候注意使用事项
四、ArrayList底层的扩容机制
得出结论:
1、如果ArrayList调用不带参数的构造方法,那么顺序表的大小为0,当第一次 add 的时候,整个数组的大小为10,当这10个放满的时候,开始扩容,以15倍的方式进行扩容。
2、如果调用指定容量大小的构造方法,那顺序表的大小就是指定的容量,如果放满了,还是以1.5倍的方式进行扩容。
五、模拟实现ArrayList
这次的实现就会比上次的更好一点,模拟源代码的实现
当创建好之后,顺序表里面的操作就按照下面的操作来写
add
在使用add函数的时候要注意,调用的 时候不带参数的构造方法,还是调用带参数的构造方法,如果满了就要扩容
public class MyArrayList<E> {private Object[] elementData;private int size;//代表有效的数据个数private static final int DEFAULT_CAPACITY = 10;private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE-8;public MyArrayList(){this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}public MyArrayList(int capacity) {//对参数进行判断if(capacity > 0){this.elementData = new Object[capacity];}else if(capacity == 0){this.elementData = new Object[0];}else {throw new IllegalArgumentException("初始化容量不能为负数");}}/*** 添加元素,添加的元素在数组的最后面,尾插* @param e* @return*/public boolean add(E e){//ensureCapacityInternal(size+1);elementData[size+1] = e;size++;return true;}private void ensureCapacityInternal(int minCapacity) {//计算出需要的容量int capacity = calculateCapacity(elementData,minCapacity);//拿着计算的容量,满了扩容,空的分配内存ensureExplicitCapacity(capacity);}private void ensureExplicitCapacity(int minCapacity) {if (minCapacity - elementData.length > 0)grow(minCapacity);}private void grow(int minCapacity) {int oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity < 0)newCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);elementData = Arrays.copyOf(elementData, newCapacity);}private static int hugeCapacity(int minCapacity) {if (minCapacity < 0)throw new OutOfMemoryError();return (minCapacity > MAX_ARRAY_SIZE) ? (Integer.MAX_VALUE) : (MAX_ARRAY_SIZE);}private static int calculateCapacity(Object[] elementData, int minCapacity) {//1、是否之前的elemenData 数组分配内存if(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA){return Math.max(DEFAULT_CAPACITY,minCapacity);}//2、分配过就返回+1的值return minCapacity;}
}
add(int index, E e) - 在指定位置插入元素
/*** 在index位置添加元素* @param index* @param e*/public void add(int index, E e) {//判断index位置是否合法rangeCheckForAdd(index);ensureCapacityInternal(size + 1); // Increments modCount!!System.arraycopy(elementData, index, elementData, index + 1,size - index);elementData[index] = e;size++;}/*** 判断index位置是否合法* @param index*/private void rangeCheckForAdd(int index){if(index < 0 || index > size){throw new IndexOutOfBoundsException("index位置不合法");}}
remove(object o) - 删除第一次遇到的元素 o
/*** 删除第一次遇见的元素 0* @param o* @return*/public boolean remove(Object o) {if (o == null) {for (int index = 0; index < size; index++)if (elementData[index] == null) {fastRemove(index);return true;}} else {for (int index = 0; index < size; index++)if (o.equals(elementData[index])) {fastRemove(index);return true;}}return false;}/*** 移动元素* @param index*/private void fastRemove(int index) {int numMoved = size - index - 1;if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index,numMoved);elementData[--size] = null; // clear to let GC do its work}
就简单的实现几个功能
面试题 - CVTE 删除第一个字符串中出现的第二个字符串中的字符
删除第一个字符串中出现的第二个字符串中的字符
例如 :
String str1= “welcome to cvte”
String str2= “come”
输出结果:wl t vte
我们遍历str1 ,看str2的字符是否在str1中,如果不在那就将这个字符放入ArrayList中,如果在那就不放进去
public static void main(String[] args) {String str1 = "welcome to cvte";String str2 = "come";ArrayList<Character> list = new ArrayList<>();for (int i = 0; i < str1.length(); i++) {char ch = str1.charAt(i);if(!str2.contains(ch+"")){list.add(ch);}}for (char ch : list) {System.out.print(ch);}}
ArrayList 实践案例 - 扑克牌
目的:
1.构造一副扑克牌
2.揭牌
class Card{private int rank;//数字private String suit;//花色public Card(String suit, int rank) {this.rank = rank;this.suit = suit;}public int getRank() {return rank;}public String getSuit() {return suit;}@Overridepublic String toString() {return "[ 花色 "+ this.suit + " " + this.rank + " ]";}
}public class Dome {//构造一副牌,这副牌里面没有大小王//四个花色private static String[] suits = {"♥","♠","♣","♦"};private static ArrayList<Card> byCard(){ArrayList<Card> cards = new ArrayList<>();//每个花色匹配不同的数字,这样就创建好了一副牌for (int i = 0; i < 4; i++) {for (int j = 1; j <=13; j++) {
// String suit = suits[i];
// Card card = new Card(suit,j);
// cards.add(card);cards.add(new Card(suits[i],j));}}return cards;}//牌创建好之后就要洗牌private static void shuFfle(ArrayList<Card> cards){// 牌数是52,数组下标就是51// 从最后一张牌开始,随机与 本身 或者 本身前面的任意一张牌 交换位置。// 这样的做交换性 比 从开头洗 的 打乱顺序的 效率 高。for (int i = cards.size()-1; i > 0 ; i--) {Random random = new Random();// 通过 Random的引用 random 去调用 nextInt() 方法。// random.nextInt() 方法,根据括号中的值,随机生成 0 ~ 括号中的值int rand = random.nextInt(i);swap(cards,i,rand);}}private static void swap(ArrayList<Card> cards,int i, int j){// 我们现在是面向对象,ArrayList虽然底层是一个数组,但是需要使用方法,才能操作数组的元素// 并不能像数组一样,直接操作// Card tmp = list[i];Card tmp = cards.get(i);// 获取 顺序表中,对应下标的元素// list[i] = list[j];cards.set(i,cards.get(j));// 将 j下标的元素,赋给 i 下标的元素,// list[j] = tmp;cards.set(j,tmp);}public static void main(String[] args) {ArrayList<Card> car = byCard();//创建牌System.out.println(car);shuFfle(car);//洗牌System.out.println(car);System.out.println("三个人轮流揭牌5张牌");ArrayList<ArrayList<Card>> hand = new ArrayList<>();ArrayList<Card> hand1 = new ArrayList<>();ArrayList<Card> hand2 = new ArrayList<>();ArrayList<Card> hand3 = new ArrayList<>();hand.add(hand1);hand.add(hand2);hand.add(hand3);//每个人轮流揭牌for (int i = 0; i < 5; i++) {for (int j = 0; j < 3; j++) {Card card = car.remove(0);hand.get(j).add(card);}}System.out.println("第一个人的牌:" + hand1);System.out.println("第二个人的牌:" + hand2);System.out.println("第三个人的牌:" + hand3);System.out.println("剩下的牌:" + car);}
}
相关文章:

java -数据结构,List相关基础知识,ArrayList的基本使用,泛型的简单、包装类介绍
一、 预备知识-泛型(Generic) 1.1、泛型的引入 比如:我们实现一个简单的顺序表 class MyArrayList{public int[] elem;public int usedSize;public MyArrayList(){this.elem new int[10];}public void add(int key){this.elem[usedSize] key;usedSize;}public …...

RabbitMQ学习总结(10)—— RabbitMQ如何保证消息的可靠性
一、丢失场景 RabbitMQ丢失的以下3种情况: (1)生产者:生产者发送消息至MQ的数据丢失...
购物车案例【版本为vue3】
前言: 首先我们要明白整个购物车的组成。它是由一个主页面加两个组件组合成的。本章主要运用父子之间的通讯: 父传子 子传父 首先新建一个vue3项目,这里有俩种创建方式: vue-cli : ● 输入安装指令 npm init vuelates…...

Multisim14 安装包及安装教程
Multisim14 安装教程 Multisim14下载地址:Kevin的学习站–安装包下载地址 Multisim14 简介: Multisim 14 是美国国家仪器有限公司(National Instrument,NI)推出的以 Windows 为基础、符合工业标准的、具有 SPICE 最佳仿…...
Java实现简单的图书管理系统源码+论文
简单图书管理系统设计(文末附带源码论文) 为图书管理人员编写一个图书管理系统,图书管理系统的设计主要是实现对图书的管理和相关操作,包括3个表: 图书信息表——存储图书的基本信息,包括书号、书名、作者…...

前端调试2
一、用chrome调试(node.js)例:const fs require(fs/promises);(async function() {const fileContent await fs.readFile(./package.json, {encoding: utf-8});await fs.writeFile(./package2.json, fileContent); })();1.先 node index.js 跑一下:2.然…...

AlphaFold 2 处理蛋白质折叠问题
蛋白质是一个较长的氨基酸序列,比如100个氨基酸的规模,如此长的氨基酸序列连在一起是不稳定的,它们会卷在一起,形成一个独特的3D结构,这个3D结构的形状决定了蛋白质的功能。 蛋白质结构预测(蛋白质折叠问题…...

问卷调查会遇到哪些问题?怎么解决?
提到问卷调查我们并不陌生,它经常被用作调查市场、观察某类群体的行为特征等多种调查中。通过问卷调查得出的数据能够非常真实反映出是市场的现状和变化趋势,所以大家经常使用这个方法进行调查研究。不过,很多人在进行问卷调查的时候也会遇到…...

量化选股——基于动量因子的行业风格轮动策略(第1部分—因子测算)
文章目录动量因子与行业轮动概述动量因子的理解投资视角下的行业轮动现象投资者视角与奈特不确定性动量因子在行业风格上的效果测算动量因子效果测算流程概述1. 行业选择:申万一级行业2. 动量因子选择:阿隆指标(Aroon)3. 测算方法…...

工作常用git命令
修改hard:git reset --hard md5git push -f合并多次commitsgit rebase -i HEAD~4git push -f冲突文件被覆盖冲突文件被覆盖了,可以用git checkout commitId /path来快速把一个或一些文件还原会之前的提交,重新commit ,merge一次删除分支git b…...

test3
数据链路层故障分析 一、网桥故障 a.主要用途简述 网桥作为一种桥接器,可以连接两个局域网。工作在数据链路层,是早期的两端口二层网络设备。可将一个大的VLAN分割为多个网段,或者将两个以上的LAN互联为一个逻辑LAN,使得LAN上的…...
领证啦,立抵3600,软考证书到手后还有很多作用
2022年下半年软考合格证书发放在2023年2月-3月进行,目前已有多个省市开始发证了,比如上海、江苏、辽宁、浙江、山东等地。还没收到领证通知的考生也不要着急,可以关注当地软考办通知。 拿到证书的朋友可以去申请入户,职称评聘&am…...

响应式布局之viewport-超级简单
之前文章CSS布局之详解_故里2130的博客-CSDN博客 上面的文章可以实现响应式布局,根据浏览器的大小变化而变化,但是相对于viewport来说,之前的还是有点复杂,而使用viewport更加的简单。 当我们使用amfe-flexible的时候࿰…...
分布式计算考试资料
第一章 分布式系统的定义 分布式系统是一个其硬件或软件组件分布在连网的计算机上,组件之间通过传递信息进行通信和动作协调的系统。分布式系统的目标 资源共享(resource sharing) 一些计算机通过网络连接起来,并在这个范围内有效地共享资源。 硬件的共…...

Java修饰符和运算符,超详细整理,适合新手入门
目录 一、访问控制修饰符 1、访问权限 二、运算符 1、算术运算符 2、关系运算符 3、逻辑运算符 4、赋值运算符 5、三元运算符 一、访问控制修饰符 Java 支持 4 种不同的访问权限: private 私有的 protected 受保护的 public 公共的 default 默认 1、…...

软件功能测试包含了哪些测试项目?功能测试报告收费标准
一、软件功能测试是什么? 软件功能测试是测试人员通过执行功能测试用例逐步验证软件产品各项功能是否达到预期需求的测试过程。也是俗称的“点点点测试”,这是基础性的测试类型,软件产品的功能直接影响到用户体验,所以软件功能测试意义重大…...

Netty 学习笔记——概念篇
Netty Home Netty GitHub Netty简介 Netty是由JBOSS提供的一个java开源框架,现为 Github上的独立项目。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。 也就是说,Netty 是一个…...

元宇宙开始告别以资本为主导的野蛮生长,新的竞争格局和态势将形成
欲要成为这样一场洗牌的胜利者,元宇宙的玩家需要真正站在商业的角度,而非资本市场的角度来看待元宇宙,来寻找元宇宙的正确的发展模式和方法。原因在于,在这样一场洗牌过程当中,仅仅只是对于以往以资本为主导的发展模式…...
MySQL 5:MySQL视图
View(视图)是一个不存在的虚拟表。 其实质是根据SQL语句获取动态数据集并命名。 用户只需要使用视图名就可以获取结果集,并作为表来使用。数据库中只存储了视图的定义,不存储视图中的数据。 这些数据存储在原始表中。当使用视图查…...
中国干细胞医疗行业市场规模及未来发展趋势
中国干细胞医疗行业市场规模及未来发展趋势近年来,中国干细胞医疗行业发展迅速,市场规模不断扩大,发挥着越来越重要的作用。根据最新统计数据显示,2018年,中国干细胞医疗行业市场规模达到1242.6亿元,比上一…...

JavaSec-RCE
简介 RCE(Remote Code Execution),可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景:Groovy代码注入 Groovy是一种基于JVM的动态语言,语法简洁,支持闭包、动态类型和Java互操作性,…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

DingDing机器人群消息推送
文章目录 1 新建机器人2 API文档说明3 代码编写 1 新建机器人 点击群设置 下滑到群管理的机器人,点击进入 添加机器人 选择自定义Webhook服务 点击添加 设置安全设置,详见说明文档 成功后,记录Webhook 2 API文档说明 点击设置说明 查看自…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...