第十章 字符串

概念

单个字符可以用char类型保存,多个字符组成的文本就需要保存在String对象中,string通常被称为字符串,一个String对象最多可以保存(2^{32}-1)个字节,占4GB空间大小的文本内容

String类

声明字符串

在Java中由双引号(“ ”)包围的都是字符串,不能作为其他数据类型来使用

可以通过下面的语法格式来声明字符串变量:


String  str

String:指定该变量为字符串类型

str:任意有效的标识符,表示字符串变量的名称 

声明的字符串变量必须经过初始化才能用,否则编译器会报出“变量未被初始化错误”

 创建字符串(初始化)

Java中字符串作为对象来处理,因此可以像创建其他类一样来创建字符串对象。创建对象要使用类的构造方法。String类的常用构造方法如下:

1.String(char a[])

该方法用一个字符数组a创建String对象,代码如下:

char a[ ]={'g','o','o','d'};

                                               等价于 ------->String s=new String("good");

String s=new String(a);

2.String(char a[ ],int offsrt,int length)

该方法提取字符串数组中的一部分创建一个字符对象,offsrt表示截取开始的位置,length表示截取的长度代码如下:

char a[ ] ={'s','t','u','d','e','n','t'};

                                                       等价于------->String s=new String("uden");

String s=new String(a,2,4);

第一个数字初始索引,第二个数字是个数范围

//字符串变量初始化	传入字符类型数组,两个数字
	//第一个数字初始索引,第二个数字是个数范围
	char [] cha= {'s','t','u','d','e','n','t'};
	String str=new String(cha,1,3);//设置范围
	System.out.println(str);

字符串常量的引用赋值来创建字符串

除了以上几种使用String类的构造方法来创建字符串变量外,还可以通过将字符串常量的引用赋值给一个字符串来创建字符串。代码如下:

String str,str2;

str="we are str";

str2="we are str2";

以上内容代码总结 


public class Test1 {

	public static void main(String[] args) {
	//字符串变量的声明
	String s;
	//字符串变量初始化
	s="你好";
	//底层运行,就是调用构造方法,和第八行的代码意义相同
	s=new String("你好");
	System.out.println(s);
	//字符串变量初始化	传入字符类型数组
	char [] ch= {'g','o','o','d'};
	String st=new String(ch);
	System.out.println(st);
	//字符串变量初始化	传入字符类型数组,两个数字
	//第一个数字初始索引,第二个数字是个数范围
	char [] cha= {'s','t','u','d','e','n','t'};
	String str=new String(cha,1,3);//设置范围
	System.out.println(str);
	
	}

}

 连接字符串

连接多个字符串

使用+运算符可以实现连接多个字符串的内容。+运算符可以连接多个String对象并产生一个新的String对象

例题10.1:先连接一幅对联的上下联,在分行输出在控制台上

String字符串之间相连接,并输出

package ten;

public class Join {//创建类

	public static void main(String[] args) {//主函数
		String s1=new String("春色绿千里");//声明String对象s1
		String s2=new String("马蹄香万家");//声明String对象s2
		String s=s1+"\n"+s2;//连接s1,s2,并赋值给s
		System.out.println(s);//输出s
	}

}

 连接其他数据类型

字符串也可以同其他基本数据类型进行连接,如果将字符串同其他数据类型相连接,会将其他数据类型的数据直接转换成字符串

例题10.2:统计每天的阅读和上机时间

实现将字符串与整型、浮点型变量相连的结果输出

package ten;

public class Link {//创建类

	public static void main(String[] args) {//主函数
		int booktime=4;//声明变量booktime
		float practice=2.5f;//声明变量practice
		//将字符串与整型、浮点型变量相连,并将结果输出
		System.out.println("我每天花费"+booktime+"小时看书;"
		+practice+"小时上机练习");

	}

}

 只要+运算符的一个操作数是字符串,编译器就会将另一个操作数转换成字符串形式,所以应该谨慎的将其他数据类型的数据与字符串相连,以免出现意想不到的结果

如果将输出语句改为

System.out.println("我每天花费"+booktime+"小时看书;"

+(practice+booktime)+"小时上机练习");

结果就会变为

 

 这是由于运算符是有优先级的,圆括号的优先级最高,所以先被执行,然后再将结果与字符串相连

获取字符串信息

获取字符串长度

使用String类的length()方法可获取声明字符串对象的长度,语法如下:

str.length();

 其中,str为字符串对象

获取字符串长度,代码如下:

String str="we are students";

int size=str.length();

System.out.println(size);//输出

查找字符串中某元素的位置

查找字符串里第一次出现该元素出现的位置元素

承载类型 位置名=字符串对象.indexOf (要搜索的字符串);

 查找字符串里最后一次出现该元素出现的位置元素

承载类型 位置名=字符串对象.lastIndexOf(要搜索的字符串);

如果lastIndexOf()方法中的是空格字符串“”(注意没有空格),则返回的结果与调用length()方法的返回结果相同         

例题10.3:用两种方式判断字符串的长度


public class Text {

	public static void main(String[] args) {
		String str="we are students";
		int size=str.lastIndexOf("");//将字符串在str中索引位置赋值给变量size
		System.out.println("空字符串字符串中str中的索引位置是:"+size);
		System.out.println("字符串str的长度是:"+str.length());
	}

}

获取指定索引号的字符

使用charAt()方法可将指定索引处的字符返回,语法如下:

 char   名字=字符串对象.charAt(索引);

例题10.4:查看指定索引位置上的字符


public class Ref {

	public static void main(String[] args) {
		String str="hello world";
		char mychar=str.charAt(6);//将字符串str中索引位置是6的字符返回
		System.out.println("字符串str中索引位置是6的字符为:"+mychar);
	}

}

 

 字符串操作

获取子字符串

通过String类的substring()方法可对字符串进行截取。substring()方法被两种不同的重载形式来满足不同的需要

substring(前索引)

该方法返回的是从指定的索引位置开始截取直到该字符串结尾的子串,语法如下:


字符串对象.substring(前索引);

在字符串中空格占用一个索引位置 

 substring(前索引,后索引)前含后不含

该方法返回的是从字符串某一索引位置开始植物某一索引位置结束的子串,语法如下:

字符串对象.substring(前索引,后索引);

例题10.5:《将进酒》的作者是哪位诗人?


public class Subs {

	public static void main(String[] args) {
		String str="《将进酒》:李白(唐)";
		String substr=str.substring(6, 8);//对字符串进行截取
		System.out.println("《将进酒》的作者是"+substr);

	}

}

去除空格

trim()方法返回字符串的副本,忽略前后的空格,语法如下:

字符串对象.trim();

只能去除首尾的空格,如果要去除所有空格要用字符串的替换才能实现

例题10.6:去掉字符串首、尾的空格 


public class Blak {

	public static void main(String[] args) {
			String str="    java    class   ";
			System.out.println("字符串原来的长度:"+str.length());
			//将字符串去掉首尾的空格后的长度生成
			System.out.println("字符串原来的长度:"+str.trim().length());
	}

}

字符串的替换

replace()可实现将指定的字符或字符串替换成新的字符或字符串,语法如下:

字符串对象.replace(要替换的内容,新的内容);

 replace()方法返回的结果是一个新的字符串,如果该字符串要替换的内容不存在字符串对象中将原字符串返回

例题10.7:将单词中的字母a替换为字母A


public class NewStr {//创建类

	public static void main(String[] args) {//主函数
		String str="address";//定义字符串str
		String newstr=str.replace("a", "A");//将str中的“a”替换成“A”并返回新字符串newstr
		
		System.out.println(newstr);//输出

	}

}

要替换的字符要与原字符串中的字符大小写保持一致 ,否则不能成功替换

判断字符串的开始与结尾

startsWith()方法与endsWith()方法分别用于判断字符串是否以指定的内容开始或结束。这两个方法返回值都为Boolean类型。

startsWith()方法

该方法用于判断当前字符串对象的前缀是否为参数指定的字符。语法如下:

字符串对象.startsWith(String 作为前缀的字符串);

endsWith()方法

该方法用于判断当前字符串是否为以给定的子字符串结束。语法如下:

字符串对象.endsWith(String 作为后缀的字符串)

例题10.8:判断字符串是否以指定的内容开始或结束


public class StartOrEnd {//创建类

	public static void main(String[] args) {//主函数
		String num1="22045612";//定义字符串
		String num2="21304578";//定义字符串
		boolean b=num1.startsWith("22");//判断字符串num1是否以22开始
		boolean b2=num2.endsWith("78");//判断字符串num2是否以78结束
		System.out.println("字符串num1是以‘22’开始的吗?"+b);//输出
		System.out.println("字符串num2是以‘78’结束的吗?"+b2);

	}

}

判断字符串是否相等 

字符串对象进行比较不能简单的使用比较运算符==

因为这是比较字符串的地址是否相同,即使两个字符串内容相同,但内存地址是不同的,使用比较运算符仍然会返回false,因此,要比较两个字符串内容是否相等,应该使用equals()方法和equalsIgnoreCase()方法

equals()方法

如果两个字符串具有相同的字符和长度,则使用equals()方法进行比较时,返回true,否则返回false,语法如下:

要比较字符串对象.equals(String 要比较的字符串对象)

equalsIgnoreCase()方法

使用equalsIgnoreCase()方法可以忽略大小写的情况下进行判断两个字符串是否相等,返回结果是Boolean类型,语法如下:

要比较字符串对象.equalsIgnoreCase(String 要比较的字符串对象)

例题10.9:判断abc和ABC是否相等


public class Opinion {//创建类10.9

	public static void main(String[] args) {//主函数
		String s1=new String("abc");//创建字符串对象
		String s2=new String("ABC");//创建字符串对象
		boolean b=s1.equals(s2);//使用equals比较s1,s2
		boolean b2=s2.equalsIgnoreCase(s2);//使用equalsIgnoreCase比较s1,s2
		System.out.println(s1+"equals"+s2+":"+b);//输出
		System.out.println(s1+"equlasIgnoreCase"+s2+":"+b2);

	}

}

按Unicode顺序比较两个字符串

compare()方法为按字典顺序比较两个字符串,该比较基于字符串中各个字符的Unicode码,按字

典顺序将String对象表示的字符序列与参数字符串所表示的字符序列进行比较

前面比后面则比较结果为一个负整数,后面比前面则比较结果为一个正整数,如果两个字符串相等,则结果为零

要比较的字符串对象.compareTo(String 被比较的字符串对象)

compareTo()方法 只有在equals(Object)方法返回true时才返回0

 例题10.10:判断字母b的位置


public class Wordbook {

	public static void main(String[] args) {
		//用于比较的字符串
		String str=new String("b");
		String str2=new String("a");
		String str3=new String("c");
		System.out.println(str+"compareTo"+str2+"."+str.compareTo(str2));
		//将str和str2比较的结果输出
		System.out.println(str+"compareTo"+str3+"."+str.compareTo(str3));
		将str和str3比较的结果输出
	}

}

字母大小写转换

 String类的toLowerCase()方法可将字符串中的所有大写字母改为小写字母,

toUpperCase()方法可将字符串中所有小写字母改为大写字母

toLowerCase()方法

将字符串中的所有大写字母转换为小写,。如果字符串中没有应该被转换的字符,则将原字符串返回,字符串长度不变,语法如下:

要转换的字符串.toLowerCase()

 toUpperCase()方法

将字符串中所有的小写字母转换为大写,如果字符串中没有应该被转换的字符,则将原字符串返回,字符串长度不变,语法如下:

要转换的字符串.toUpperCase()

 使用 toLowerCase()方法和 toUpperCase()方法进行大小写转换时,数字或其他非英文字母类字符不受影响。

例题:字母大小写转换


public class UpAndLower {//创建类

	public static void main(String[] args) {//主函数
		String str=new String("Oh My Gold!");//创建字符串
		String newstr=str.toLowerCase();//使用toLowerCase()方法进行小写转换
		String newstr2=str.toUpperCase();//使用toUpperCase()方法进行大写转换
		System.out.println(newstr);//输出
		System.out.println(newstr2);

	}

}

字符串分割

 使用split()方法可以使字符串按指定的分割字符或字符串进行分割,

并将分割后的结果存放在字符串数组

split(分割符)

该方法可根据给定的分割符对字符串进行拆分。语法如下:

字符串对象.split(分割字符串的分割符也可以使用正则表达式)

 没有统一的对字符进行分割的符号。如果想定义多个分割符,可使用符号“|”。例如,“,=”表示分割符分别为“,”和“=”。

split(分割符,分割的次数)

该方法可根据给定的分割符对字符串进行拆分,并限定拆分的次数。语法如下:

字符串对象.split(分割字符串的分割符,要分割的次数)

 例题10.12:按要求分割”192.168.0.1“


public class Division {

	public static void main(String[] args) {
		String str="192.168.0.1";//创建要分割的字符串
		String[]firstArray=str.split("\\.");//给出分割符进行分割,使用转义字符
		String[]secondArray=str.split("\\.",2);//按照分割符进行两次分割,使用转义字符
		System.out.println("str的原值为:["+str+"]");//输出原值
		System.out.println("全部分割的结果:");//输出全部分割的结果
		for(String temp:firstArray) {
			System.out.println("["+temp+"]");
		}
		System.out.println();
		System.out.println("分割两次的结果:");//输出分割两次的结果
		for(String temp:secondArray) {
			System.out.println("["+temp+"]");
		}
		System.out.println();
	}

}

 

格式化字符串

Sting 类的静态fomat()方法用于创建格式化的字符串。format()方法有两种重载形式.

format(String format,Object...args)

 该方法使用指定的格式字符串和参数返回一个格式化字符串,格式化后的新字符串使用本地默认的语言环境。语法如下:

String.format(格式字符串转换符,引用参数)

如果还有格式说明符以外的参数,则忽略这些额外的参数。此参数的数目是可变的,可以为 0。

  format(Local l,String format,Object...args)

该方法使用指定的语言环境、格式字符串和参数返回一个格式化字符串,格式化后的新字符串使用其指定的语言环境。语法如下:

String. format(语言环境,格式字符串转换符,引用参数)

 1: 格式化过程中要应用的语言环境。如果1为 null,则不进行本地化

如果还有格式说明符以外的参数,则忽略这些额外的参数。此参数的数目是可变的,可以为 0。

日期和时间字符串格式化

在应用程序设计中,经常需要显示日期和时间。如果想输出满意的日期和时间格式,一般需要编写大量的代码、经过各种算法才能实现。format()方法通过给定的特殊转换符作为参数来实现对日期和时间的格式化。

1,日期格式化 

例子,返回一个月中的天数,代码如下:

Date date=new Date();//创建对象

String s=String.format("%te",date);//通过format()方法对date进行格式化

常用的日期格式化转换符
转换符说明示例
%te一个月中的某一天(1~31)2
%tb指定语言环境的月份简称Feb(英文)、二月(中文)
%tB指定语言环境的月份全称February(英文)、二月(中文)
%tA指定语言环境的星期几全称Monday(英文)、星期一(中文)
%ta指定语言环境的星期几简称Mon(英文)、星期一(中文)
%tc包括全部日期和时间信息星期二   三月   25    13:37:22   CST   2008
%tY4 位年份2008
%tj一年中的第几天 (001~366)085
%tm月份03
%td一个月中的第几天 (01~31)02
%ty2 位年份08

例题10.13:按照格式输出今天的年、月、日

import java.util.Date;//导入Date类

public class Eval {

	public static void main(String[] args) {
		Date date =new Date();//创建对象,获取现在的时间
		String year=String.format("%tY", date);//将date进行格式化
		String month=String.format("%tB", date);
		String day=String.format("%td", date);
		//输出
		System.out.println("今年是:"+year+"年");
		System.out.println("现在是:"+month);
		System.out.println("今天是:"+day+"号");
	}

}

2.时间格式化 

使用format()方法不仅可以完成日期的格式化,也可以实现时间的格式化。

时间的格式化转换符要比日期的格式化转换符更多、更精确,它可以将时间格式化为时、分、秒、毫秒等。

时间格式化转换符
转换符说明示例
%tH2位数字的24 时制的小时(00~23)
 
14
%tI2位数字的12 时制的小时(01~12)
 
05
%tk2位数字的24时制的小时(0~23)5
%tl2位数宇的12时制的小时(1-12)10
%tM2位数字的分钟数 (00~59)05
%tS2位数字的秒数(00~60)12
%tL3位数字的毫秒数(000~999)920
%tN9位数字的微称数(000000000~999999999)062000000
%tp指定语言环境下上午成下午标记下午(中文)、pm(英文)
%tz相对于GNT  RFC  82格式的数字时区偏移量+0800
%tZ时区缩写形式的宇符申CST
%ts1970-01-01 00:00:00 至现在经过的秒数1206426646
%tQ1970-01-01 00:00:00 至现在经过的毫秒数1206426737453

例题10.14:按照格式输出当下的时、分、秒

import java.util.Date;//导入Date类

public class GetDate {

	public static void main(String[] args) {
		Date date=new Date();//创建Date对象
		String hour=String.format("%tH", date);//将date格式化
		String minute=String.format("%tM", date);
		String second=String.format("%tS", date);
		//输出
		System.out.println("现在是:"+hour+"时"+minute+"分"+second+"秒");

	}

}

 

格式化常见的日期时间组合

通过前面的时间格式化和日期格式化,我们可以知道,太过于繁琐,而日期时间组合可以减少代码量,更加简化代码

常见的日期和时间组合的格式
转换符说明示例
%tF“年-月-日”格式(4位年份)2008-03-25
%tD“月/日/年”格式(2位年份)03/25/08
%tc全部日期和时间信息星期二    三月   25  15:20:00   CST  2008
%tr“时:分:秒 PM(AM)”格式(12 时制)03:22:06   下午
%tT“时:分:秒”格式(24 时制)15:23:50
%tR“时:分”格式(24时制)15:25

 例题10.15:按照格式输出当下的年、月、日

import java.util.Date;//导入Date类

public class DateAndTime {

	public static void main(String[] args) {
		Date date=new Date();//创建Date对象
		String time=String.format("%tc", date);//将date格式化
		String form=String.format("%tF", date);
		//将格式化后的日期时间输出
		System.out.println("全部的时间信息是:"+time);
		System.out.println("年-月-日格式:"+form);
		
		

	}

}

常规类型格式化

 常规类型格式化可应用于任何参数类型

常规转换符
转换符说明示例
%b、%B结果被格式化为布尔类型true
%h、%H结果被格式化为散列码A05A5198
%s、%S结果被格式化为字符串类型“abcd"
%c、%C结果被格式化为字符类型'a'
%d结果被格式化为十进制整数40
%o结果被格式化为八进制整数11
%x、%X结果被格式化为十六进制整数4b1
%e结果被格式化为用计算机科学记数法表示的十进制数1.700000e+01
%a结果被格式化为带有效位数和指数的十六进制浮点值0X1.C000000000001P4
%n结果为特定于平台的行分隔符
%%结果为字面值“%”%

 例题10.16:使用转换符获取表达式的结果


public class General {//新建类

	public static void main(String[] args) {//主函数
		String str=String.format("%d", 400/2);//将结果以十进制格式显示
		String str2=String.format("%b", 3>5);//将结果以boolean型显示
		String str3=String.format("%x", 200);//将结果以十六进制格式显示
		//输出
		System.out.println("400的一半是:"+str);
		System.out.println("3>5正确吗:"+str2);
		System.out.println("200的十六进制数是:"+str3);

	}

}

使用正则表达式

正则表达武通常被用于判断语句,来检查某一字符串是否满足某一格式,含有一些具有特殊意义字符的字符串,称为正则表达式的元字符。

正则表达式中的元字符
元字符正则表达式中的写法意义
..任意一个字符
\d\\d0~9的任何一个数字
\D\\D任何一个非数字字符
\s\\s空白字符,如"\t、"\n"
\S\\S非空白宇符
\w\\w可用于标识符的字符,但不包括“$”
\W\\W不可用于标识符的字符
\p{Lower}\\p{Lower}小写字母a~z
\p{Upper}\\p{Upper}大写字母A~Z
\p{ASCII}\\p{ASCII}ASCII 字符
\p{Alpha}\\p{Alpha}字母字符
\p{Digit}\\p{Digit}十进制数字,即0~9
\p{Alnum}\\p{Alnum}数字或字母字符
\p{Punct}\\p{Punct}标点符号:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
\p{Graph}\\p{Graph}可见字符:[\p(Alnum)\p[Punct)]
\p{Print}\\p{Print}可打印字符:[\p(Graph)\x20]
\p{Blank}\\p{Blank}空格或制表符:[\t]
\p{Cntrl}\\p{Cntrl}控制字符:[\x00-\xlF\x7F

 在正则表达式中,“ . ”代表任何一个字符,因此在正则表达式中如果想使用普通意义的点字符"."

必须使用转义字符“\”

 限定修饰符

正则表达式中是可以使用方括号括起 若干个字符来表达一个元字符,该元字符可代表方括号中的任意一个字符。

在正则表达式中允许使用限定修饰符来限定元字符的出现

如A*,表示A可在字符串中出现0次或多次,下列是限定修饰符的表格

限定修饰符
限定修饰符意义示例限定修饰符意义示例
0次或1次A?{n}正好出现n次A{2}
*0次或多次{n,}至少出现n次A{2,}
+一次或多次{n,m}出现n~m次A{2,6}

matches()方法

 用于检测字符串是否匹配给定的正则表达式。

要匹配的字符串.matches(正则表达式)

例题:验证E-mail地址是否合法


public class Judeg {

	public static void main(String[] args) {
		//定义要匹配的正则表达式
		String regex="\\w+@\\w+(\\.\\w{2,3})*\\.\\w{2,3}";
		//定义要验证的字符串
		String str1="aaa@";
		String str2="aaaaa";
		String str3="1111@111ffyu.dfg.com";
		//判断字符串是否与表达式匹配,然后输出
		if(str1.matches(regex)) {
			System.out.println(str1+"是一个合法的E-mail地址格式");
		}
		if(str2.matches(regex)) {
			System.out.println(str2+"是一个合法的E-mail地址格式");
		}
		if(str3.matches(regex)) {
			System.out.println(str3+"是一个合法的E-mail地址格式");
		}		

	}

}

一些正则表达式

QQ邮箱:String    re="\\d{5,12}@qq.cpm";

xxxx年xx月xx日:String    re="\\d{4}年\\d{2}月\\d{2}日";

xx时xx分xx秒:      String    re="\\d{2}时\\d{2}分\\d{2}秒";

字符串生成器

使用String创建的字符串,长度是固定的,内容不能被改变和编译,虽然可以使用+追加字符串,但+会产生一个新的String空间,如果重复的这样进行修改,会消耗更多的空间内存,而JDK的StringBuilder类则可以解决这个问题。

例题10.18:效率比拼

package ten;

public class Jerque {

	public static void main(String[] args) {
		String  str="";//创建空字符串
		long StarTime=System.currentTimeMillis();//获取字符串执行前的时间
		for(int i=0;i<10000;i++) {//循环追加字符串
			str=str+i;
			
		}
		long endTime=System.currentTimeMillis();//获取字符串执行后的时间
		long time=endTime-StarTime;//计算时间差
		System.out.println("string消耗的时间:"+time);//输出
		StringBuilder builder=new StringBuilder("");//创建字符串生成器
		 StarTime=System.currentTimeMillis();//获取字符串执行前的时间
		 for(int j=0;j<10000;j++) {//循环追加字符串
				builder.append(j);
				
			}
		 endTime=System.currentTimeMillis();//获取字符串执行后的时间
		 time=endTime-StarTime;//计算时间差
		 System.out.println("stringBuilder消耗的时间:"+time);//输出
	}

}

 

 从例题中可以看出两种操作执行的时间差距很大,如果你需要在程序中频繁的追加字符,建议使用StringBuilder类

StringBuilder类

StringBuilder对象的初始容量是16字符,可以自行指定初始长度,StringBuilder对象将自动增加长度以容纳被附加的字符,如果要StringBuilder类输出字符串结果。使用 toString()方法。利用 StringBuilder 类中的方法可动态地执行添加、删除和插入等字符串的编辑操作。该类的常用方法如下:

append()方法

该方法用于向字符串生成器中追加内容。通过该方法的多个重载形式,可实现接受任何类型的数据

StringBuilder类的字符串名.append(要追加的内容(可以是任何类型的数据或者其他对象))

 insert(int offset, arg)方法

该方法用于向字符串生成器中的指定位置插入数据内容。

StringBuilder类的字符串名.insert(要插入的位置,要插入的数据)

 delete(int start , int end)方法(前删除后不删)

删除此序列的子字符串中的字符。该子字符串从指定的 start 处开始,一直到索引end-1 处的字符如果不存在这种字符,则一直到序列尾部。如果 start 等于 end,则不发生任何更改。语法如下:

StringBuilder类的字符串名.delete(要删除的字段的起始位置 ,要删除字段的结束位置) 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值