“手撕”String类+练习题

一、什么是String类

简单讲:是一个类!创建字符串和字符串方法的类。

用' '圈起来的叫字符,比如:'a','b'....里面只能有一个char类型的字符。

用" "圈起来的叫字符串,比如:"abc"..里面可以连着多个字符一起。

二、String类的使用

 String提供了很多使用方法,常见的三种如下:

//直接赋值
String s1="zhangsan";
//String类是类,可以直接new对象
String s2=new String("zhangsan");
//用字符间接创造字符串
char[] arr={'o','w','s','p','q'};
String s3=new String(arr);

注意:

 String是引用类型,所以它里面存的不是字符串,是地址。让我们看看代码:

并且它源码里面是由char类型的数组组成的,还有个hash值,默认是0。 

public static void main(String[] args) {
// s1和s2引用的是不同对象 s1和s3引用的是同一对象String s1 = new String("hello");String s2 = new String("world");String s3 = s1;System.out.println(s1.length()); // 获取字符串长度---输出5System.out.println(s1.isEmpty()); // 如果字符串长度为0,返回true,否则返回false
}

 为什么s1和s2引用的是不同对象呢?

答:因为s1和s2分别new对象出来,new的时候,会创造不同的空间存放值。

 

其中:在Java中“”引起来的也是String类型对象。 

// 打印"hello"字符串(String对象)的长度
System.out.println("hello".length());

三、String类的字符串操作 

String对象的比较

1. ==比较引用对象时,注意==比较的是地址!!!若是基本类型,就是比数值。

public static void main(String[] args) {int a = 10;int b = 20;int c = 10;
// 对于基本类型变量,==比较两个变量中存储的值是否相同System.out.println(a == b); // falseSystem.out.println(a == c); // true
// 对于引用类型变量,==比较两个引用变量引用的是否为同一个对象String s1 = new String("hello");String s2 = new String("hello");String s3 = new String("world");String s4 = s1;System.out.println(s1 == s2); // falseSystem.out.println(s2 == s3); // falseSystem.out.println(s1 == s4); // true
}

 2. boolean equals(Object anObject) 方法:按照字典序比较

Object中equals默认按照==比较,String类重写了父类Object中equals方法

public static void main(String[] args) {String s1 = new String("hello");String s2 = new String("hello");String s3 = new String("Hello");
// s1、s2、s3引用的是三个不同对象,因此==比较结果全部为falseSystem.out.println(s1 == s2); // falseSystem.out.println(s1 == s3); // false
// equals比较:String对象中的逐个字符
// 虽然s1与s2引用的不是同一个对象,但是两个对象中放置的内容相同,因此输出true
// s1与s3引用的不是同一个对象,而且两个对象中内容也不同,因此输出falseSystem.out.println(s1.equals(s2)); // trueSystem.out.println(s1.equals(s3)); // false
}

 ==比的是地址,而String重写后的equals比的是字符串相同

3.int compareTo(String s) 方法: 按照字典序进行比较 

可能的疑问:不是有equals了吗,为什么还需要compareTo方法?

答:equals比的是相不相同,compareTo比的是谁大谁小  

public static void main(String[] args) {String s1 = new String("abc");String s2 = new String("ac");String s3 = new String("abc");String s4 = new String("abcdef");System.out.println(s1.compareTo(s2)); // 不同输出字符差值-1System.out.println(s1.compareTo(s3)); // 相同输出 0System.out.println(s1.compareTo(s4)); // 前k个字符完全相同,输出长度差值 -3
}

具体的比较方法:

1. 先按照字典次序大小比较,如果出现不等的字符,直接返回这两个字符的大小差值

2. 如果前k个字符相等(k为两个字符长度最小值),返回值两个字符串长度差值 

4. int compareToIgnoreCase(String str) 方法:与compareTo方式相同,但是忽略大小写比较 

public static void main(String[] args) {String s1 = new String("abc");String s2 = new String("ac");String s3 = new String("ABc");String s4 = new String("abcdef");System.out.println(s1.compareToIgnoreCase(s2)); // 不同输出字符差值-1System.out.println(s1.compareToIgnoreCase(s3)); // 相同输出 0System.out.println(s1.compareToIgnoreCase(s4)); // 前k个字符完全相同,输出长度差值 -3
}

字符串的查找

字符串查找也是字符串中非常常见的操作,String类提供的常用查找的方法:

方法功能
char charAt(int index)返回index位置上字符,如果index为负数或者越界,抛出 IndexOutOfBoundsException异常
int indexOf(int ch)返回ch第一次出现的位置,没有返回-1
int indexOf(int ch, int fromIndex)从fromIndex位置开始找ch第一次出现的位置,没有返回-1
int indexOf(String str)返回str第一次出现的位置,没有返回-1
int indexOf(String str, int fromIndex)从fromIndex位置开始找str第一次出现的位置,没有返回-1
int lastIndexOf(int ch)从后往前找,返回ch第一次出现的位置,没有返回-1
int lastIndexOf(int ch, int fromIndex)从fromIndex位置开始找,从后往前找ch第一次出现的位置,没有返 回-1
int lastIndexOf(String str)从后往前找,返回str第一次出现的位置,没有返回-1
int lastIndexOf(String str, int fromIndex)从fromIndex位置开始找,从后往前找str第一次出现的位置,没有返回-1
public static void main(String[] args) {String s = "aaabbbcccaaabbbccc";System.out.println(s.charAt(3)); // 'b'System.out.println(s.indexOf('c')); // 6System.out.println(s.indexOf('c', 10)); // 15System.out.println(s.indexOf("bbb")); // 3System.out.println(s.indexOf("bbb", 10)); // 12System.out.println(s.lastIndexOf('c')); // 17System.out.println(s.lastIndexOf('c', 10)); // 8System.out.println(s.lastIndexOf("bbb")); // 12System.out.println(s.lastIndexOf("bbb", 10)); // 3
}

字符串的转换

1.数值和字符串互转 

public static void main(String[] args) {
// 数字转字符串String s1 = String.valueOf(1234);String s2 = String.valueOf(12.34);String s3 = String.valueOf(true);String s4 = String.valueOf(new Student("Hanmeimei", 18));System.out.println(s1);System.out.println(s2);System.out.println(s3);System.out.println(s4);System.out.println("=================================");
// 字符串转数字
// 注意:Integer、Double等是Java中的包装类型,在我之前包装类博客讲过int data1 = Integer.parseInt("1234");double data2 = Double.parseDouble("12.34");System.out.println(data1);System.out.println(data2);
}

 2.大小写转化

public static void main(String[] args) {String s1 = "hello";String s2 = "HELLO";
// 小写转大写System.out.println(s1.toUpperCase());
// 大写转小写System.out.println(s2.toLowerCase());
}

 3.字符串转数组

public static void main(String[] args) {String s = "hello";
// 字符串转数组char[] ch = s.toCharArray();
for (int i = 0; i < ch.length; i++) {System.out.print(ch[i]);
}System.out.println();
// 数组转字符串String s2 = new String(ch);System.out.println(s2);
}

 4.格式化

public static void main(String[] args) {String s = String.format("%d-%d-%d", 2019, 9,14);System.out.println(s);
}

字符串的替换

方法功能
String replaceAll(String regex, String replacement)替换所有的指定内容
String replaceFirst(String regex, String replacement)替换收个内容
    String str = "helloworld" ;System.out.println(str.replaceAll("l", "_"));System.out.println(str.replaceFirst("l", "_"));

注意事项: 由于字符串是不可变对象,替换不修改当前字符串, 而是产生一个新的字符串。下面会解释。

字符串的拆分

方法功能
String[] split(String regex)将字符串全部拆分
String[] split(String regex, int limit)将字符串以指定的格式,拆分为limit组
String str = "hello world hello bit" ;
String[] result1 = str.split(" ") ; // 按照空格拆分,全拆分
String[] result2 = str.split(" ",2) ; // 按照空格拆分,拆两个for(String s1: result1) {
System.out.println(s1);
}
for(String s2: result2) {
System.out.println(s2);
}
//执行结果
hello
world
hello
bit
hello
world hello bit

 注意:要用数组来接收。

有些特殊字符作为分割符可能无法正确切分, 需要加上转义。

String str = "192.168.1.1" ;
String[] result = str.split("\\.") ;
for(String s: result) {
System.out.println(s);
}

注意事项:

1. 字符"|","*","+"都得加上转义字符,前面加上 "\\" 。

2. 而如果是 "\" ,那么就得写成 "\\\\" 。

3. 如果一个字符串中有多个分隔符,可以用"|"作为连字符。

字符串的截取

方法功能
String substring(int beginIndex)从指定索引截取到结尾
String substring(int beginIndex, int endIndex)截取部分内容
String str = "helloworld" ;
System.out.println(str.substring(5));
System.out.println(str.substring(0, 5));

注意事项:

1. 索引从0开始

2. 注意前闭后开区间的写法, substring(0, 5) 表示包含 0 号下标的字符, 不包含 5 号下标 

大小写和去空格方法

方法功能
String trim()去掉字符串中的左右空格,保留中间空格
String toUpperCase()字符串转大写
String toLowerCase()字符串转小写
String str = " hello world " ;
System.out.println("["+str+"]");
System.out.println("["+str.trim()+"]");String str = " hello%$$%@#$%world 哈哈哈 " ;
System.out.println(str.toUpperCase());
System.out.println(str.toLowerCase());

小提示:trim 会去掉字符串开头和结尾的空白字符(空格, 换行, 制表符等),大小写只转换字母

四、字符串的不可变性

 简单来说:就是字符串这玩意儿的值不能改。让我们通过源码:

提出误区:

我们可以看出value和String都是由final修饰的,但这并不是它不可以被修改的理由!

final修饰是(String类和value指向)不能被继承的意思!!!

比如:下面代码array数组也是final修饰,只是它的地址(指向),它里面的数字却可以修改,也就是说final并不是字符串不可变性的原因!

public static void main(String[] args) {final int array[] = {1,2,3,4,5};array[0] = 100;System.out.println(Arrays.toString(array));
// array = new int[]{4,5,6}; // 编译报错:Error:(19, 9) java: 无法为最终变量array分配值
}

正确理解:

因为就是说我们要是能拿到array的地址(指向)就可以改变这个不可变性,

但是!!!它是由private修饰的,它就是不给你拿到这个值!

为什么 String 要设计成不可变的?(不可变对象的好处是什么?)

1. 方便实现字符串对象池。 如果 String 可变,那么对象池就需要考虑写时拷贝的问题了。

2. 不可变对象是线程安全的。

3. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中。

五、字符串的修改

注意:尽量避免直接对String类型对象进行修改,因为String类是不能修改的,所有的修改都会创建新对象,效率非常低下。 

public static void main(String[] args) {String s = "hello";s += " world";System.out.println(s); // 输出:hello world
//上面的原理(或者说背后实现)的代码是下面String s2="hello";StringBuilder stringBuilder=new StringBuilder();stringBuilder.append(s2);stringBuilder.append("world");s2=stringBuilder.toString();System.out.println(s2);
}

但是这种方式不推荐使用,因为其效率非常低,中间创建了好多临时对象。

public static void main(String[] args) {long start = System.currentTimeMillis();String s = "";
for(int i = 0; i < 10000; ++i){s += i;
}long end = System.currentTimeMillis();System.out.println(end - start);start = System.currentTimeMillis();StringBuffer sbf = new StringBuffer("");
for(int i = 0; i < 10000; ++i){sbf.append(i);
}end = System.currentTimeMillis();System.out.println(end - start);start = System.currentTimeMillis();StringBuilder sbd = new StringBuilder();
for(int i = 0; i < 10000; ++i){sbd.append(i);
}end = System.currentTimeMillis();System.out.println(end - start);
}
//执行结果
144
1
2

可以看待在对String类进行修改时,效率是非常慢的,因此:尽量避免对String的直接需要,如果要修改建议尽量 使用StringBuffer或者StringBuilder。 

StringBuffer s1 = new StringBuffer("");
for(int i = 0; i < 10000; ++i){s1.append(i);
}
StringBuilder s2 = new StringBuilder("");
for(int i = 0; i < 10000; ++i){s2.append(i);
}

它两不像String一样,每次都要重新new一个对象,也可以说是一劳永逸。

六、StringBuilder类和StringBuffer类

方法功能
StringBuff append(String str)在尾部追加,相当于String的+=,可以追加:boolean、char、char[]、 double、float、int、long、Object、String、StringBuff的变量
char charAt(int index)获取index位置的字符
int length()获取字符串的长度
int capacity()获取底层保存字符串空间总的大小
void ensureCapacity(int mininmumCapacity)扩容
void setCharAt(int index, char ch)将index位置的字符设置为ch
int indexOf(String str)返回str第一次出现的位置
int indexOf(String str, int fromIndex)从fromIndex位置开始查找str第一次出现的位置
int lastIndexOf(String str)返回最后一次出现str的位置
int lastIndexOf(String str, int fromIndex)从fromIndex位置开始找str最后一次出现的位置
StringBuff insert(int offset, String str)在offset位置插入:八种基类类型 & String类型 & Object类型数据
StringBuffer deleteCharAt(int index)删除index位置字符
StringBuffer delete(int start, int end)删除[start, end)区间内的字符
StringBuffer replace(int start, int end, String str)将[start, end)位置的字符替换为str
String substring(int start)从start开始一直到末尾的字符以String的方式返回
String substring(int start,int end)将[start, end)范围内的字符以String的方式返回
StringBuffer reverse()反转字符串
String toString()将所有字符按照String的方式返回
public static void main(String[] args) {StringBuilder sb1 = new StringBuilder("hello");StringBuilder sb2 = sb1;
// 追加:即尾插-->字符、字符串、整形数字sb1.append(' '); // hellosb1.append("world"); // hello worldsb1.append(123); // hello world123System.out.println(sb1); // hello world123System.out.println(sb1 == sb2); // trueSystem.out.println(sb1.charAt(0)); // 获取0号位上的字符 hSystem.out.println(sb1.length()); // 获取字符串的有效长度14System.out.println(sb1.capacity()); // 获取底层数组的总大小sb1.setCharAt(0, 'H'); // 设置任意位置的字符 Hello world123sb1.insert(0, "Hello world!!!"); // Hello world!!!Hello world123System.out.println(sb1);System.out.println(sb1.indexOf("Hello")); // 获取Hello第一次出现的位置System.out.println(sb1.lastIndexOf("hello")); // 获取hello最后一次出现的位置sb1.deleteCharAt(0); // 删除首字符sb1.delete(0,5); // 删除[0, 5)范围内的字符String str = sb1.substring(0, 5); // 截取[0, 5)区间中的字符以String的方式返回System.out.println(str);sb1.reverse(); // 字符串逆转str = sb1.toString(); // 将StringBuffer以String的方式返回System.out.println(str);
}

 从上述例子可以看出:String和StringBuilder最大的区别在于String的内容无法修改,而StringBuilder的内容可以修改。频繁修改字符串的情况考虑使用StringBuilder。

七、String的习题

第一题:

String str = new String("ab"); // 会创建多少个对象
String str = new String("a") + new String("b"); // 会创建多少个对象

第一个会创建2个:

一个是new的对象,一个是“ab”在常量池的对象

第二个会创建6个:

new出来2个对象,常量池“a”和“b”两个,底层调用StringBuilder又一个对象,StringBuilder转字符串toString调用又一个对象,一共六个。

 第二题:

public class Example{String str = new String("good");char[ ] ch = { 'a' , 'b' , 'c' };public static void main(String args[]){Example ex = new Example();ex.change(ex.str,ex.ch);System.out.print(ex.str + " and ");System.out.print(ex.ch);}public void change(String str,char ch[ ]){str = "test ok";ch[0] = 'g';}
}

分析:

ex有两个变量ch和str。ex指向ch和str(ch和str也是引用对象)存的的地址,指向good和abc。

这时候调用change方法,把str和ch传过去,但请注意:!!它会再开辟两个空间存change的str和ch(相当于String 形参str=实参str,这两个str是不同的)。

由于字符串的不可变性,修改的时候会重新申请一段内存存“test ok”,但是数组里面的值却可以修改(ch地址不能改,但值可以)。

所以change里面的str就改为test ok(是新的空间和内存),但是原本在main方法里面的实参str却没有修改,所以还是good,但是!数组里面却修改成gbc。

答案是good and gbc

第三题

求字符串中第一个唯一的字符

解释题目:

给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1 。

解题思路:

用一个数组有26个空间,代表每一个a,b,c等每一个字符,

由于数组是从0索引,我们可以把字符串的每个字符拿出来减去字符a,比如‘a’-‘a'==0,刚刚好从0索引,同理其他字符也如此。

遍历字符串,遇到字符就++,再遍历一遍字符串,第一个为1的字符就是第一个唯一的字符。

class Solution {public int firstUniqChar(String s) {int[] count=new int[26];for(int i=0;i<s.length();i++){char ch=s.charAt(i);count[ch-'a']++;}for(int i=0;i<s.length();i++){char ch=s.charAt(i);if(count[ch-'a']==1){return i;}}return -1;}
}

注意点:

1.数组要用int类型,因为里面存的是一个字符的次数,是数字整型

2.对于字符串的遍历要用length()这个方法。

3.从字符串取字符用charAt()这个方法

4.要遍历2次,一次是为了计数,第二次才是为了找到第一个唯一的数

4.第四题

字符串最后一个单词的长度

题目解释:

计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾) 

输入:

hello nowcoder

输出:

8

说明:

最后一个单词为nowcoder,长度为8   
import java.util.Scanner;
public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String s=sc.nextLine();String[] str=s.split(" ");int count=0;for(int i=0;i<str[str.length-1].length();i++){count++;}System.out.print(count);}}

解题思路:

先输入一个值,用s接收

用split()方法分割,取最后一个

把这个放到for循环中遍历,看看有多少个字符

第五题 

验证是否回文

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 

输入: s = "A man, a plan, a canal: Panama"
输出:true
解释:"amanaplanacanalpanama" 是回文串。

废话不多说,代码如下: 

class Solution {public boolean isPalindrome(String s) {s = s.toLowerCase();//转换为小写int left = 0;int right = s.length()-1;while (left < right) {while (left < right && !isCharacterNum(s.charAt(left))) {left++;}while (left < right && !isCharacterNum(s.charAt(right))) {right--;}//left下标 是合法的字符//right下标 是合法的字符if(s.charAt(left) == s.charAt(right)) {left++;right--;}else {return false;}}return true;}//判断是不是 数字 字符 和  字母字符private boolean isCharacterNum(char ch) {// if(ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9') {//     return true;// }// return false;if(Character.isDigit(ch) || Character.isLetter(ch)) {return true;}return false;}  
}

 

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

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

相关文章

如何搭建Sphinx文档

环境准备 Linux CentOS 7 方案 搭建一个文档网站&#xff0c;本文档使用的是tomcatsphinx。 Tomcat可以快速搭建出http服务&#xff0c;也可以使用apache httpd。 Sphinx作为文档网页自动生成工具&#xff0c;可以从reStructured文档转换为html文件。 Tomcat安装 创建/…

华为设备WLAN配置之AP上线

WLAN基础配置之AP上线 配置WLAN无线网络的第一阶段&#xff0c;AP上线技术&#xff1a; 实验目标&#xff1a;使得AP能够获得来自AC的DHCP地址服务的地址&#xff0c;且是该网段地址池中的IP。 实验步骤&#xff1a; 1.把AC当作三层交换机配置虚拟网关 sys Enter system view,…

【XuperChain】一、搭建第一条区块链节点

一、准备环境&#xff1a; 下载git和golang即可 apt install git apt install golang二、拉取代码&#xff0c;编译XuperChain 通过此命令拉取XuperChain源码到本地 git clone https://github.com/xuperchain/xuperchain.git 拉取成功后&#xff0c;会代码保存到了xuperChain…

使用Python生成一束玫瑰花

520到了&#xff0c;没时间买花&#xff1f;我们来生成一个电子的。 Python不仅是一种强大的编程语言&#xff0c;用于开发应用程序和分析数据&#xff0c;它也可以用来创造美丽的艺术作品。在这篇博客中&#xff0c;我们将探索如何使用Python生成一束玫瑰花的图像。 准备工作…

TransFormer学习之VIT算法解析

1.算法简介 本文主要对VIT算法原理进行简单梳理&#xff0c;下图是一个大佬整理的网络整体的流程图&#xff0c;清晰明了&#xff0c;其实再了解自注意力机制和多头自注意力机制后&#xff0c;再看VIT就很简单了 受到NLP领域中Transformer成功应用的启发&#xff0c;ViT算法尝…

详解ArcGIS 水文分析模型构建

目录 前言 项目环境、条件 Dem 数据预览 ArcGIS模型构建器 模型搭建 填洼 流向 流量 河流长度 栅格计算器 河流链接 河网分级 栅格河网矢量化 绘制倾泻点 栅格流域提取 集水区 盆域分析 栅格转面 模型应用 导出 py 文件 完善脚本 最终效果 结束语 前言 …

【时间复杂度和空间复杂度之间的故事】

【时间复杂度和空间复杂度之间的故事】 一.前言 二.时间复杂度定义时间复杂度的计算规则习题 三.空间复杂度定义计算方法习题空间复杂度 O(1)空间复杂度 O(n) 本文主要讲解关于时间复杂度与空间复杂度 &#x1f600;&#x1f603;&#x1f601;&#x1f601;&#x1f607;&…

FastAPI单元测试:使用TestClient轻松测试你的API

当使用FastAPI进行单元测试时&#xff0c;一个重要的工具是TestClient类。TestClient类允许我们模拟对FastAPI应用程序的HTTP请求&#xff0c;并测试应用程序的响应。这使我们能够在不启动服务器的情况下对API进行全面的测试。 下面我将详细讲解TestClient的使用方法和常见操作…

10大桌面软件前端框架,那个是您的最爱呢?

桌面端前端框架是用于构建桌面应用程序的前端框架&#xff0c;以下是一些常用的桌面端前端框架&#xff1a; 1. Electron&#xff1a; Electron是一个开源的桌面应用程序开发框架&#xff0c;可以使用HTML、CSS和JavaScript构建跨平台的桌面应用程序&#xff0c;例如VS Code、…

2024 年第四届长三角高校数学建模竞赛赛题B题超详细解题思路+代码分享

B题 人工智能范式的物理化学家 问题一问题二问题三问题四问题五完整代码与文档获取 B题思路详细解析分享给大家&#xff0c;还会继续更新完成具体的求解过程&#xff0c;以及全部的代码与技术文档&#xff0c;都会直接给大家分享的哦~需要完整代码直接看到最后哦 问题一 针对问…

谈谈【软件测试的基础知识,基础模型】

关于软件测试的基本概念和基本模型 前言一个优秀的测试人员具备的素质关于需求测试用例软件错误(BUG)概念开发模型瀑布模型&#xff08;Waterfall Model&#xff09;螺旋模型&#xff08;Spiral Model&#xff09; 前言 首先,什么是软件测试? 通俗来讲:软件测试就是找BUG&…

【配置】雷池WAF社区版安装

官方文档点击跳转 什么是雷池 雷池&#xff08;SafeLine&#xff09;是长亭科技耗时近 10 年倾情打造的 WAF&#xff0c;核心检测能力由智能语义分析算法驱动。 什么是 WAF WAF 是 Web Application Firewall 的缩写&#xff0c;也被称为 Web 应用防火墙。 区别于传统防火墙…

记某src通过越权拿下高危漏洞

在挖掘某SRC时&#xff0c;遇到了一个社区网站&#xff0c;社区站点是我在挖掘SRC时比较愿意遇到的&#xff0c;因为它们可探索的内容是较多的&#xff0c;幸运地&#xff0c;通过两个接口构造参数可进行越权&#xff0c;从而获得整个网站用户的信息。 图片以进行脱敏处理。在…

单词可交互的弧形文本

在一个项目中&#xff0c;要求把少儿读本做成电子教材呈现出来&#xff0c;电子书的排版要求跟纸质书一致。其中&#xff0c;英语书有个需求&#xff1a;书中有些不规则排版的文本&#xff08;如下图所示&#xff09;&#xff0c;当随书音频播放时&#xff0c;被读到的文本要求…

gin框架学习笔记(四) ——参数绑定与参数验证

参数绑定 前言 在Gin框架中我们可以利用bind来将前段传递过来的参数与结构体进行参数绑定与参数校验&#xff0c;而这bind的方式主要有以下两种: Mustbind:一般使用较少&#xff0c;因为参数校验失败会改变状态码Shouldbind&#xff1a;主要使用上的校验方法&#xff0c;校验…

Elasticsearch - HTTP

文章目录 安装基本语法索引创建索引查看索引删除索引 文档创建文档更新文档匹配查询多条件查询聚合查询映射 安装 https://www.elastic.co/downloads/past-releases/elasticsearch-7-17-0 下载完成启动bin/elasticsearch服务&#xff0c;可以在Postman调试各种请求。 基本语法…

高稳定LED驱动IC防干扰数显驱动控制器热水器LED驱动芯片VK1650 SOP16/DIP16 原厂FAE支持

产品型号&#xff1a;VK1650 产品品牌&#xff1a;永嘉微电/VINKA 封装形式&#xff1a;SOP16/DIP16 工程服务&#xff0c;技术支持&#xff01; 概述 VK1650是一种带键盘扫描电路接口的 LED 驱动控制专用芯片&#xff0c;内部集成有数据锁存器、LED 驱动、键盘扫描等电路。…

2024年职称评审流程大揭秘,顺利拿下职称

上半年时间不急&#xff0c;中旬太忙&#xff0c;没有时间&#xff0c;下半年干着急。评职称一定要趁早&#xff0c;不然卡住一个流程&#xff0c;今年就不需要评职称了。中级副高级职称评职称就像挤公交你不努力挤一把&#xff0c;就只能等下一趟下一趟。所以评职称一定要看准…

[Cocos Creator 3.5赛车游戏] 第4节 创建汽车节点

在实现汽车节点之前&#xff0c;我们要先熟悉一下少量的基本概念&#xff0c;这样才能让您更快的实现第一个汽车节点。 一、基本概念 1.什么是节点&#xff1a; 在Cocos中&#xff0c;场景是由一系列节点组成的&#xff0c;每个节点下面又可以有子节点&#xff0c;而每个节点都…

Axure RP 9 for Mac:强大的原型设计利器

Axure RP 9 for Mac是一款功能强大的原型设计工具&#xff0c;专为Mac用户打造。它支持高保真度的应用程序和网站原型设计&#xff0c;帮助用户快速创建高质量的产品原型。软件内置丰富的交互效果和动画设计选项&#xff0c;设计师可以通过简单的操作&#xff0c;为原型添加各种…