一、包装类
包装类的分类 (Wrapper)
- 针对八种基本数据类型相应的引用类型--包装类
- 有了类的特点,就可以调用类中的方法。
基本数据类型
包装类
boolean
Boolean
char
Character
double
Double
int
Integer
byte
Byte
short
Short
float
Float
long
Long
后六个的父类都为Number。
(1)我们查看Boolean的源码:
我们进入类图如下所示:
Boolean实现了Serializable和Comparable接口。
(2)我们查看Character的源码:
我们查看他的类图:
Character类实现了Serializable和Comparable。
(3)我们查看Byte类:
我们进行查看他的类图:
我们查看剩下的类图:
Float\Double\Intger\Byte\Short\Long 都继承自Number类,实现了Comparable,同时也实现了Serializable接口。
包装类和基本数据的转换
演示 包装类和基本数据类型的相互转换,这里以int和Integer演示。
(1)jdk5前的手动装箱和拆箱方式,装箱:基本类型 ->包装类型,反之,拆箱:包装类型 -->基本类型
(2)jdk5 以后(含jdk5)的自定装箱和拆箱方式
(3)自动装箱底层调用的是valueOf方法,比如Integer.valueOf( )
(4 )其它包装类的用法类似。
我们查看示例如下所示:
package com.ypl.wrapper; public class Integer01 { public static void main(String[] args) { //演示int <-->Integer的装箱和拆箱 //装箱: int -->Integer //拆箱: Integer -->int //jdk5前是手动装箱和拆箱 //手动装箱 int ->Integer int n1=100; //方式1: Integer integer = new Integer(n1); //方式2: Integer integer1 = Integer.valueOf(n1); //手动拆箱 Integer -->int int i = integer.intValue(); //jdk5后,就可以自动装箱和自动拆箱 int n2=200; //自动装箱 int ->Integer Integer integer2=n2; //底层使用的是Integer.valueOf(n2)。 //我们进行debug,我们进入底层发现源码如下所示: /** * public static Integer valueOf(int i) { * if (i >= IntegerCache.low && i <= IntegerCache.high) * return IntegerCache.cache[i + (-IntegerCache.low)]; * return new Integer(i); * } */ //自动拆箱 Integer -->int int n3=integer2; //底层仍然使用的是intValue()方法 //我们继续进行debug,我们进入底层发现源码如下所示: /** * public int intValue() { * return value; * } */ } }
课堂测试题:
下面的代码是否正确,为什么?
Double d=100d; //ok,自动装箱 Double.valueOf(100d); Float f=1.5f; //ok,自动装箱 Float.valueOf(1.5f);
如下两个题目输出结果相同吗?各是什么?
Object obj1=true?new Integer(1):new Double(2.0); //三元运算符【是一个整体】 如果为真,则返回第一个值,如果为假,则返回第二个值。 System.out.println(obj1);//什么? 输出1.0,Double会提升优先级。
Object obj2; if(true) obj2=new Integer(1); else obj2=new Double(2.0); System.out.println(obj2); 输出什么? 1,分别计算,是独立的,不会提示优先级
我们在编译软件上实际编码如下:
package com.ypl.wrapper; public class WrapperExercise01 { public static void main(String[] args) { Double d=100d; //ok,自动装箱 Double.valueOf(100d); Float f=1.5f; //ok,自动装箱 Float.valueOf(1.5f); Object obj1=true?new Integer(1):new Double(2.0); //三元运算符【是一个整体】 如果为真,则返回第一个值,如果为假,则返回第二个值。 System.out.println(obj1);//什么? 输出1.0,Double会提升优先级。 Object obj2; if(true) obj2=new Integer(1); else obj2=new Double(2.0); System.out.println(obj2); } }
运行之后如下所示:
包装类型和String类型的相互转换
我们示例代码如下所示:
package com.ypl.wrapper; public class WrapperVSString { public static void main(String[] args) { //案例演示,以Integer和String转换为例,其他类似: //包装类(Integer) -->String //1.自动装箱 //2.toString方法 //3.valueOf方法 Integer i= 100; //自动装箱 //方式1,i本身没有变化 String str1=i+""; //方式2 String str2 = i.toString(); //方式3 String str3 = String.valueOf(i); /* public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); } valueOf底层为Object对象,而Integer本身就是从Object过来的。 */ //String -->包装类(Integer) //1.Integer的parseInt方法 //2.Integer的构造器的形式 String str4="123450"; Integer i2 = Integer.parseInt(str4); //使用到自动装箱 /* 我们查看parseInt的底层代码: public static int parseInt(String s) throws NumberFormatException { return parseInt(s,10); } */ Integer i3 = new Integer(str4); //构造器 /* 我们查看构造器的源码如下所示: public Integer(String s) throws NumberFormatException { this.value = parseInt(s, 10); } */ System.out.println("ok----"); } }
我们运行之后如下所示:
我们发现没有问题。
包装类(Integer类和Character类)的常用方法
我们发现Integer有很多种方法:
我们选择常见的方法如下所示:
Integer.MIN_VALUE(返回最小值)
Integer.MAX_VALUE(返回最大值)
我们发现Character的方法如下所示:
Character.isDigit(判断是不是数字)
Character.isLetter(判断是不是字母)
Character.isUpperCase(判断是不是大写)
Character.isLowerCase(判断是不是小写)
Character.isWhitespace(判断是不是空格)
Character.toUpperCase(转成大写)
Character.toLowerCase(转成小写)
我们的代码示例如下所示:
package com.ypl.wrapper; public class WrapperMethod { public static void main(String[] args) { System.out.println(Integer.MIN_VALUE);//返回最小值 System.out.println(Integer.MAX_VALUE);//返回最大值 System.out.println(Character.isDigit('a')); //判断是不是数字 System.out.println(Character.isLetter('a'));//判断是不是字母 System.out.println(Character.isUpperCase('a'));//判断是不是大写 System.out.println(Character.isLowerCase('a'));//判断是不是小写 System.out.println(Character.isWhitespace('a'));//判断是不是空格 System.out.println(Character.toUpperCase('a'));//转成大写 System.out.println(Character.toLowerCase('A'));//转成小写 } }
我们运行之后如下所示:
Integer类面试题1:
我们的代码如下所示:
package com.ypl.wrapper; public class method1 { public static void main(String[] args) { Integer i = new Integer(1); Integer j = new Integer(1); System.out.println(i==j); //False,不是同一个对象 //所以,这里主要是看范围 -128 ~127就是直接返回 Integer m=1; //底层 Integer.valueOf(1); ->阅读源码 Integer n=1; //底层 Integer.valueOf(1); ->阅读源码 /** * 1.如果i在IntegerCache.low(-128)~IntegerCache.high(127),包括-128和127,就直接从数组返回 * 2.如果不在-128~127,就直接new Integer(i) * public static Integer valueOf(int i) { * if (i >= IntegerCache.low && i <= IntegerCache.high) * return IntegerCache.cache[i + (-IntegerCache.low)]; * return new Integer(i); * } * 我们继续追加的时候,我们发现 * private static class IntegerCache { * static final int low = -128; * static final int high; * static final Integer cache[]; * * This method will always cache values in the range -128 to 127, inclusive, * and may cache other values outside of this range. */ System.out.println(m==n); //返回True. //所以,这里主要是看范围 -128 ~127就是直接返回 //否则,就new Integer(xx); Integer x=128;//底层 Integer.valueOf(128); Integer y=128;//底层 Integer.valueOf(128); /** * public static Integer valueOf(int i) { * if (i >= IntegerCache.low && i <= IntegerCache.high) * return IntegerCache.cache[i + (-IntegerCache.low)]; * return new Integer(i); * } */ System.out.println(x==y); //128不在范围内,因此就返回false。 Integer a=127;//底层 Integer.valueOf(127); Integer b=127;//底层 Integer.valueOf(127); //所以,这里主要是看范围 -128 ~127就是直接返回,包括-128和127 /** * public static Integer valueOf(int i) { * if (i >= IntegerCache.low && i <= IntegerCache.high) * return IntegerCache.cache[i + (-IntegerCache.low)]; * return new Integer(i); * } */ System.out.println(a==b); //127在范围内,因此就返回true。 } }
我们运行之后如下所示:
我们可以更加详细的查看我们的源码,我们进行debug,如下所示:
我们追加之后,我们发现如下所示:
我们发现 IntegerCache.cache里面东西已经创建好了,而且最低为-128,最高为127。
下来我们继续看待一道Integer类面试题:
我们的代码如下所示:
package com.ypl.wrapper; public class WrapperExercise03 { public static void main(String[] args) { //示例一 Integer i1 = new Integer(127); Integer i2 = new Integer(127); System.out.println(i1==i2); //返回false //示例二 Integer i3 = new Integer(128); Integer i4 = new Integer(128); System.out.println(i3==i4); //返回false //示例三,取值范围在-128~127,直接返回 Integer i5=127; //底层Integer.valuesOf(127) Integer i6=127; //底层Integer.valueOf(127) System.out.println(i5==i6); //返回true //示例四,超出直接返回的取值范围 ~128-127。 Integer i7=128; Integer i8=128; System.out.println(i7==i8); //返回false //示例五 Integer i9=127; //底层Integer.valuesOf(127) Integer i10 = new Integer(127); /** * public static Integer valueOf(int i) { * if (i >= IntegerCache.low && i <= IntegerCache.high) * return IntegerCache.cache[i + (-IntegerCache.low)]; * return new Integer(i); * } */ System.out.println(i9==i10); //返回false。 //示例六,只要有基本数据类型,判断的是值是否相等。 Integer i11=127; int i12=127; System.out.println(i11==i12); //返回true,会自动装箱 //示例七,只要有基本数据类型,判断的是值是否相等。 Integer i13=128; int i14=128; System.out.println(i13==i14); //返回true. } }
我们运行之后如下所示:
二、String类
String类的理解和创建对象
(1)String对象用于保存字符串,也就是一组字符序列
(2)字符串常量对象是用双引号括起的字符序列。例如:“你好”、“12.97”、“boy"等
(3)字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节
char占两个字节
(4)String类较常用构造器(其他看手册):
String s1=new String( );
String s2=new String(String original);
String s3=new String(char[ ] a);
String s4=new String(char[ ] a,int startIndex(从哪里开始),int count(多少个字符))
我们设计如下代码:
public class String01 {
public static void main(String[] args) {
//String对象用于保存字符串,也就是一组字符序列
String name="jack";
}
}
我们进入String的底层源码:
我们查看他的类图:
String实现了Serializable这个接口,说明String可以串行化,String对象是可以在网络上传输的。
String实现了Comparable这个接口,说明String对象可以相互比较大小。
String实现了CharSequence这个接口,实现字符序列。
我们查看String的构造器:
我们的设计如下所示:
package com.ypl.String;
public class String01 {
public static void main(String[] args) {
//1.String对象用于保存字符串,也就是一组字符序列
//2."jack"字符串常量,双引号括起的字符序列
//3.字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节,char占两个字节
//4.String类有很多构造器,构造器的重载
//常用的有
//String s1=new String( );
//String s2=new String(String original);
//String s3=new String(char[] a);
//String s4=new String(char[] a,int startIndex,int count)
//String s5=new String(byte[] b)
//5.String类实现了接口Serializable(String可以串行化:可以在网络传输)
//6.String类实现了接口Comparable(String对象可以比较大小,利用compareTo方法。
//7.String类是final类,不能被其他的类继承
/**
* 8.String有属性 private final char value[];用于存放字符串内容
* 我们的字符串常量真正存储在String源码里面的:
* private final char value[];
* 在底层仍然是一个char数组。字符串本质仍然是一个char数组。
*/
//9.一定要注意:value是一个final类型,不可以修改(不是字符不可以修改,而是里面的地址不可以修改,即指向存储的地址不可以修改,
// 而所指向的地址存储的值是可以修改的):即value不能指向新的地址,但是单个字符内容是可以变化的。
final char value[] ={'a','b','c'};
char[] v2={'t','o','m'};
value[0]='H';
value=v2;
String name="jack";
}
}
为了更清晰的了解:
一定要注意:value是一个final类型,不可以修改(不是字符不可以修改,而是里面的地址不可以修改,即指向存储的地址不可以修改, // 而所指向的地址存储的值是可以修改的):即value不能指向新的地址,但是单个字符内容是可以变化的。
我们设计代码如下:
final char value[] ={'a','b','c'};
char[] v2={'t','o','m'};
value[0]='H';
value=v2;
//value=v2;不可以修改value地址
这样子是有错误的:
不能给value再分配一个新的变量
当我们修改代码如下所示时:
char value[] ={'a','b','c'};
char[] v2={'t','o','m'};
value[0]='H';
value=v2;
我们如下所示:
我们拿掉final发现是可以的了,final是为了约束不能指向一个新的空间。单独的是可以允许的。
创建String对象的两种方式:
(1)方式一:直接赋值String s="rgflfbc"
先从常量池查看是否有"rgflfbc"数据空间,如果有,直接指向;如果没有则重新创建,然后指向。s最终指向的是常量池的空间地址。
jvm的内存:String的内存布局
(2) 方式二:调用构造器 String s=new String("rgflfbc");
先在堆中创建空间,里面维护了value属性,指向常量池的rgflfbc空间。如果常量池没有"rgflfbc",重新创建,如果有,直接通过value指向。最终指向的是堆中的空间地址。
我们进行如下测试:
测试题1:
我们的代码如下所示:
package com.ypl.String;
public class StringExercise01 {
public static void main(String[] args) {
String a="abc";
String b="abc";
System.out.println(a.equals(b)); //true
System.out.println(a==b); //true
}
}
我们运行之后如下所示:
测试题2:
package com.ypl.String;
public class StringExercise01 {
public static void main(String[] args) {
String a1 =new String("abc");
String a2 =new String("abc") ;
System.out.println(a1.equals(a2)); //true
System.out.println(a1==a2); //false
}
}
运行之后如下所示:
测试题3:
我们的代码设计如下所示:
package com.ypl.String;
public class StringExercise02 {
public static void main(String[] args) {
String a="rgf"; //a指向常量池的"rgf"
String b=new String("rgf"); //b指向堆中的对象 value
System.out.println(a.equals(b)); //true
System.out.println(a==b); //false,a指向常量池,b指向堆中的对象 value。
System.out.println(a==b.intern());//查看intern方法,在API里面查看,返回true,在常量池里面查看是否有b对象的字符串,如果有则返回。
System.out.println(b==b.intern());b指向堆,即堆中的对象value,b.intern返回常量池的地址。
}
}
b.intern( )方法最终返回的是常量池的地址(对象)
我们运行之后如下所示:
我们通过菜鸟教程找到了中文版的API,intern方法的概述如下所示:‘
调用intern方法时,如果池已包含等于此String方法确定的String
对象的字符串(用equals(Object)方法确定),则返回池中的字符串。 否则,将此String
对象添加到池中,并返回对此String
对象的引用。
测试题4:
我们设计的代码如下所示:
package com.ypl.String;
public class StringExercise03 {
public static void main(String[] args) {
String s1="rgfedu";//指向常量池"rgfedu"
String s2="java";//指向常量池"java"
String s4="java";//指向常量池"java"
String s3=new String("java");//指向堆中对象
System.out.println(s2==s3);//false,s2指向常量池,s3指向堆
System.out.println(s2==s4);//true,都指向常量池
System.out.println(s2.equals(s3));//true,常量池里面的值相等
System.out.println(s1==s2 );//false,常量池里面的值不相等
}
}
我们运行之后如下所示:
测试题5:
我们设计的代码如下所示:
package com.ypl.String;
public class StringExercise04 {
public static void main(String[] args) {
Person p1=new Person();
p1.name="rgfedu";
Person p2 = new Person();
p2.name="rgfedu";
System.out.println(p1.name.equals(p2.name)); //true,两个值相等
System.out.println(p1.name== p2.name);//true,指向两个同一样的常量,p1.name和p2.name不是new的,而是直接给的常量值
System.out.println(p1.name=="rgfedu");//true,与常量池里面的一样。
String s1 = new String("bcde");
String s2 = new String("bcde");
System.out.println(s1==s2);//都是new出来的,即堆里面的value指向常量池里面的同一个值。但是堆的地址不同,即为false.
}
}
class Person{
String name;
int age;
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
我们运行之后如下所示:
字符串的特性:
(1)String是一个final类,代表不可变的字符序列
(2)字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的。
我们思考如下问题:
(1)以下语句创建了几个对象?
String s1="hello";
s1="haha";
由于字符串是不可变得,所以我们刚开始创建的指向hello对象的s1,在创建haha对象之后,s1不再指向hello,而是指向haha。所以是创建了两个对象。
(2)
String a="hello"+"abc";
创建了几个对象?
String a="hello"+"abc"; //==>优化等价 String a="helloabc"
创建了一个对象。
分析:
1.编译器很聪明,做一个优化,判断创建的常量池对象,是否有引用指向
2.String a="hello"+"abc";==>String a="helloabc"
(3)
String a="hello"; //创建a对象
String b="abc"; //创建b对象
String c=a+b;
创建了几个对象?
我们通过具体的debug来进行查看:
1.
2. 我们step into追进去之后如下所示:
我们发现我们进入了StringBuilder的构造器里面了,第一步为先创建了一个StringBuilder sb=StringBuilder();sb是在堆中。
3.执行sb.append("hello");其中append是在原来字符串的基础上追加的
3.我们跳出去再继续追进去如下所示:
执行sb.append("abc");
4.我们再跳出去再追进去:
调用sb.toString()方法,
5.此时c的内容为helloabc了。
最后其实是c指向堆中的对象(String)value[ ]-->池中的”helloabc"
一共有三个对象,如上所示。
我们进行测试如下:
package com.ypl.String; public class StringExercise05 { public static void main(String[] args) { String a="hello"; //创建a对象 String b="abc"; //创建b对象 String d="helloabc"; String c=a+b; System.out.println(c==d); } }
运行之后如下所示:
重要规则:String ci="ab"+"cd";常量相加,看的是池。
String c1=a+b;变量相加,是在堆中。
(4)
package com.ypl.String;
public class StringExercise06 {
public static void main(String[] args) {
String s1="rgfedu"; //s1指向常量池中的"rgfedu"。
String s2="java"; //s2指向常量池中的"java"。
String s5="rgfedujava"; //s5指向常量池中的"rgfedujava"。
String s6=(s1+s2).intern(); //s6指向池中的"rgfedujava"。
//调用intern方法时,如果池已包含等于此String方法确定的String对象的字符串(用equals(Object)方法确定),
// 则返回池中的字符串。否则,将此String对象添加到池中,并返回对此String对象的引用。
System.out.println(s5==s6); //true
System.out.println(s5.equals(s6)); //true
}
}
我们运行之后如下所示:
(5) 下列程序运行的结果是什么,
我们的代码如下所示:
package com.ypl.String;
public class StringExercise07 {
String str=new String("rgf");
final char[] ch={'j','a','v','a'};
public void change(String str,char ch[]) {
str="java";
ch[0]='h';
}
public static void main(String[] args) {
StringExercise07 ex=new StringExercise07();
ex.change(ex.str,ex.ch);
System.out.print(ex.str+" and "); //rgf
System.out.println(ex.ch);//hava
}
}
我们运行之后如下所示:
String类的常用方法:
String类是保存字符串常量的。每次更新都需要重新开辟空间,(创建对象,重新指向)效率极低,因此java设计者还提供了StringBuilder和StringBuffer来增强String的功能,并提高效率。
equals //区分大小写,判断内容是否相等
equalsIgnoreCase //忽略大小写的判断内容是否相等
length //获取字符的个数,字符串的长度
indexOf //获取字符在字符串中第1次出现的索引,索引从0开始,如果找不到,返回-1
lastIndexOf //获取字符在字符串中最后一次出现的索引,索引从0开始,如找不到,返回-1
substring //截取指定范围的子串
trim //去前后空格
charAt:获取某索引处的字符,注意不能使用Str[index]这种方式。
我们设计的代码如下所示:
package com.ypl.String;
public class StringMethod01 {
public static void main(String[] args) {
//1.equals,比较内容是否相等,区分大小写
String str1="hello";
String str2="Hello";
System.out.println(str1.equals(str2)); //false
//2.equalsIgnoreCase 忽略大小写的判断内容是否相等
String str3="hello";
String str4="Hello";
System.out.println(str3.equalsIgnoreCase(str4)); //true
String username="Rgf";
if("rgf".equalsIgnoreCase(username)){
System.out.println("Success!");
}else {
System.out.println("Failure");
}
//3.length 获取字符的个数,字符串的长度
System.out.println("rgf".length());//3
//4.indexOf获取字符在字符串对象中第一次出现的索引,索引从0开始,如果找不到,返回-1.
String s1="wer@ter";
int index=s1.indexOf('r');
System.out.println(index);//2
//5.lastIndexOf获取字符在字符串中最后一次出现的索引,索引从0开始,如果找不到,返回-1.
String s2="wer@ter";
int inde=s2.lastIndexOf('r');
System.out.println(inde);//6
//6.substring 截取指定范围的子串
String name="hello,rgf";
//从索引0开始截取2前面的内容
System.out.println(name.substring(0,2));
//从索引6开始截取后面所有的内容
System.out.println(name.substring(6)); //截取后面的字符
}
}
我们运行之后如下所示:
我们设计的代码如下所示:
//1.indexOf获取字符在字符串对象中第一次出现的索引,索引从0开始,如果找不到,返回-1.
String s1="wer@ter";
System.out.println("weIndexOf="+s1.indexOf("we")); //0
我们运行之后如下所示:
其他常用方法:
toUpperCase //转换成大写
toLowerCase //转换成小写
concat
replace 替换字符串中的字符
split 分割字符串,对于某些分割字符,我们需要转义比如 | \\等
compareTo //比较两个字符串的大小
toCharArray //转换成字符数组
format //格式字符串,%s字符串 %c字符 %d 整型 %.2f浮点型
我们设计的代码如下所示:
package com.ypl.String;
public class StringMethod02 {
public static void main(String[] args) {
//1.toUpperCase ,转换成大写
String s="heLLo";
System.out.println(s.toUpperCase()); //HELLO
//2.toLowerCase,转换成小写
System.out.println(s.toLowerCase()); //hello
// 3.concat拼接字符串
String s1="宝玉";
s1=s1.concat("林黛玉").concat("薛宝钗").concat("together");
System.out.println(s1);
//4.replace替换字符串中的字符
String s2="宝玉 and 薛宝钗 薛宝钗 薛宝钗";
//s2.replace()方法执行后,返回的结果才是替换过的。
//注意对s1没有任何影响
s2=s2.replace("薛宝钗","林黛玉");
System.out.println(s2);
//5.split分割字符串,对于某些分割字符,我们需要转义比如 | \\等
String poem="锄禾日当午,汗滴河下土,谁知盘中餐,粒粒皆辛苦";
//以,为标准对这首诗进行分割,就返回一个数组。
String[] split=poem.split(",");
System.out.println("==这首诗的内容是==");
for(int i=0;i<split.length;i++){
System.out.println(split[i]);
}
//在对字符串进行分割的时候,如果有特殊字符,需要加入转义符\ ,如下\\\\,\转义符 \ \转义符 \.
String poem1="E:\\aaa\\bbb";
String[] split1 = poem1.split("\\\\");
for (int j=0;j<split1.length;j++){
System.out.println(split1[j]);
}
//6.toCharArray 转换成字符数组
s="happy";
char[] chs = s.toCharArray();
for (int i=0;i<chs.length;i++){
System.out.println(chs[i]);
}
//7.compareTo 比较两个字符串的大小,如果前者大,则返回正数,后者大,则返回负数,如果相等,返回0
//(1)如果长度相同,并且每个字符也相同,就返回0.
//(2)如果长度相同或者长度不相同,但是在进行比较时可以区分大小,就返回的是
// if(c1!=c2){
//return c1-c2;
//}
//即从不相同的字符开始相减。
//(4)如果长度不同,如果前面的部分都相同,就返回str1.len-str2.len
String a="jchn";
String b="jack";
System.out.println(a.compareTo(b)); //返回值是'c'-'a'=2的值
//我们进行查看源码如下所示:
/*
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
*/
//8.format格式字符串
//占位符有:
// %s 字符串 %c 字符 %d 整型 %.2f浮点型
String name="john";
int age=10;
double score=98.3/3;
char gender='男';
//将所有信息都拼接在一个字符串
String info="我的姓名是"+name+"年龄是"+age+",成绩是"+score+"性别是"+gender+"。希望大家喜欢我";
System.out.println(info);
//(1)%s,%d,%.2f,%c称为占位符。
//(2)这些占位符由后面的变量来替换
//(3)%s表示后面由字符串来进行替换
//(4)%d是整数来替换
//(5)%.2f表示使用小数来替换,替换后只会保留小数点两位,并且进行四舍五入的处理。
//(6)%c使用char类型来替换
String info2=String.format("我的姓名是%s年龄是%d,成绩是%.2f性别是%c.希望大家喜欢我!",name,age,score,gender);
System.out.println("info="+info2);
}
}
我们运行之后如下所示: