1. Scanner 类
a) 用来干什么的?
b) 构造方法有哪些?
Scanner
(InputStream source)
构造一个新的 Scanner
,它生成的值是从指定的输入流扫描的。
c) 方法有哪些?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
|
|
|
|
d) 使用过程中有什么常见的问题?
i. 抛出InputMismatchException
Scanner sc=new Scanner(System.in);int a=sc.nextInt();
需要输入的是一个int类型的数,如果不是或者超过了int的范围就会报错
sad
Exception in thread "main" java.util.InputMismatchException
ii. nextLine方法失效的问题
package wbl.test;
import java.util.Scanner;
public class Scanner_Test
{
public static void main(String[] args)
{
/*
*如果说获取下一行和其他获取方式一起获取的时候会出现问题,
*该问题会导致后面的nextLine()方法失效。
*原因:nextLine()方法以分隔符作为查找的条件,如果找到了则跳过以后的内容
*,当我们输入10和回车的时候实际是输入了10 /r/n
* nextInt()方法获取到10,nextLine()方法获取到了 /r/n。然后不再关心
* 后面的内容了,所以输入失效。
* */
Scanner sc=new Scanner(System.in);
int a=sc.nextInt();
String str=sc.nextLine();
String str4=sc.nextLine();
System.out.println("a="+a+','+"str="+str+','+"str4="+str4);
//问题:只执行了nextInt就结束了
//解决方法1
/*sc=new Scanner(System.in);
String str1=sc.nextLine();
System.out.println("a="+a+','+"str1="+str1);*/
//解决方法二:将String类型数据转换为int数据类型
/*String str2=sc.nextLine();
//问题:输入的类型和需要的类型不一样:int i=str2;
//解决:类型转换
int i=Integer.parseInt(str2);//将字符串转换为int类型,字符串只能是数字
int j=i;
String str3=sc.nextLine();
System.out.println(j);
System.out.println("str2="+str2+','+"str3="+str3);*/
}
}
问题执行结果:
10
dasd
a=10,str=,str4=dasd
2、String类
a) 干啥的
从JDK1.0 版本开始:String
类代表字符串。Java 程序中的所有字符串字面值(如 "abc"
)都作为此类的实例实现。
字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。
b) 构造方法
|
|
|
|
package wbl.test;
public class String_Constructor
{
public static void main(String[] args)
{
String string1=new String();//创建一个空的字符串对象
System.out.println(string1);
/**
* String(byte[] byte)构造方法
* 注意事项:使用byte数组取创建字符串对象的时候,byte数组的值会被当成Unicode编码
*/
byte[] bs={97,98,99};
String string2=new String(bs);
System.out.println(string2);
char[] cs={'你','好'};
String string3=new String(cs);
System.out.println(string3);
}
}
执行结果:
abc
你好
c) 成员方法
|
char[] cs={'你','好'}; |
| |
|
|
|
|
|
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
String string=new String("asdasdasfgsd"); |
|
String string=new String("asdasdasfgsd"); System.out.println(string.indexOf('a',5));//6 |
| |
|
|
|
|
|
|
|
|
|
|
| |
| |
| |
|
|
|
|
| |
String string=new String("asdasdas1fgsdasaa"); | |
|
|
| |
| |
| |
| |
|
|
package wbl.test;
public class String_Test1
{
public static void main(String[] args)
{
split("afasdafgfsdf","sd");
getBytes("asd");
equals("asd","asD");
concat("ni","hao");
compareto("abc","Abc");
// startEnd("asdasdjlkdla");
// daxiaoxie("sdadDASD");
// contains("adkjkaheiqu","j");
replase("asdhkjhwqdsje","d","p");
// indexof("qweiouuslkdfj;akd",'u');
String string=new String(" asdasdDASDASdasaa ");
String sub=string.substring(5);
System.out.println(sub.toLowerCase());
System.out.println(sub.toUpperCase());
System.out.println(string.trim());
char[] arr={'s','d','a','w'};
System.out.println(new String().valueOf(arr));
// System.out.println(string.hashCode());
// System.out.println(string.indexOf("as"));
}
/**
* 根据字符s,将字符串string切成几段,如果字符串没有字符s就不拆分
* 拆分的子字符串用数组去接收,子字符串不包含s,s可以是单个字符或者子字符串
* @param string
*/
private static void split(String string,String s)
{
String[] strings= string.split(s);
for (int i = 0; i < strings.length; i++)
{
System.out.println(strings[i]);
}
}
/**
* 将字符串一个一个的编写为byte值(ASCII码),将结果存在byte数组中
* getBytes(string,0,5):将字符串string中底0到5个字符转换为byte值并存到byte数组中
* @param string
*/
private static void getBytes(String string)
{
byte[] bytes=string.getBytes();
for (int i = 0; i < bytes.length; i++)
{
System.out.println(bytes[i]);
}
}
/**
* 判断两个字符串值是否相等,String的equals方法已经被重写,不然比较的是地址
*/
private static void equals(String string,String string2)
{
System.out.println(string.equals(string2));
System.out.println(string.equalsIgnoreCase(string2));//不考虑大小写
}
/**
* 将后面的字符串拼接在前面字符串的尾部
* @param string
* @param string2
*/
private static void concat(String string,String string2)
{
System.out.println(string.concat(string2));
}
/**
* 比较两个字符串,大于返回正整数,小于返回负整数,等于返回0,字符串每个字符依次比较
* 相等比较下一个,大小与长度无关,比较的是ASCII码,用前者-后者,返回结果
* 如果string2是string 的子集,那么返回的结果就是1
* @param string
* @param string2
*/
private static void compareto(String string,String string2)
{
char[] arr={'a','b','d'};
System.out.println(string.copyValueOf(arr));
System.out.println(string.compareTo(string2));//区分大小写
System.out.println(string.compareToIgnoreCase(string2));//不区分大小写
}
/**
*判断字符串是否以什么开头,以什么结束,结果返回true或false
*/
private static void startEnd(String string) {
System.out.println(string.startsWith("as"));
System.out.println(string.endsWith("if"));
}
/**
* 查找一个字符串中某个字符第一次出现的位置和最后一次出现的位置
* indexof(String string,char c,int d):查找字符串string中第d位字符开始,字符c第一次出现的位置;
*/
private static void indexof(String string,char c)
{
System.out.println(string.indexOf("u"));//返回指定子字符串在此字符串中第一次出现处的索引。
System.out.println(string.indexOf(c));
System.out.println(string.lastIndexOf(c));
}
/**
* 替换字符串中的某一个字符
* string.replace(cs1, cs2):将字符串string中的字符cs1替换为cs2
* string2.replaceAll("asd", "s")将字符串string2中的子字符串asd,替换为s。如果没有这个
* 子字符串则不替换
*/
private static void replase(String string,CharSequence cs1,CharSequence cs2)
{
String string2=string.replace(cs1, cs2);
System.out.println(string2);
System.out.println(string2.replaceAll("asd", "s"));
}
/**
* 判断字符串中是否存在另一个字符串
*/
private static void contains(String str,CharSequence count)
{
System.out.println(str.contains(count));
}
/**
* 大小写转换
*/
private static void daxiaoxie(String str)
{
String str1=str.toUpperCase();
String str2=str.toLowerCase();
System.out.println(str1);
System.out.println(str2);
}
}
d) 面试题
package wbl.test;public class String_Test2
{
public static void main(String[] args)
{
//demo();
//demo1();
demo2();
demo3();
demo4();
}
private static void demo4()
{
String str = new String("abc");//创建了6个对象
String str2 = new String("ab") + new String("c");
System.out.println(str == str2);
System.out.println(str.equals(str2));
}
private static void demo3()
{
String str = "ab";
String str1 = str + "c";
String str2 = "abc";//创建了三个对象,因为不知道str具体是什么,不能常量优化
System.out.println(str1 == str2);
System.out.println(str1.equals(str2));
}
private static void demo2()
{
byte b = 4 + 5; // b = 9; java是有常量优化机制的,在编译的时候他会将自己能计算的先计算出来
String str = "a" + "b" + "c";
String str1 = "abc";//创建了一个对象
System.out.println(str == str1);
System.out.println(str.equals(str1));
}
private static void demo1()
{
/**
* 首先到常量池中去查找是否有"abc"这个字符串,如果没有则创建,然后放入到常量池中,如果有则直接返回产量池的地址
* 当使用现有的字符串在创建新的字符串的时候是使用的常量池中的内容直接复制过去,所以现有对象是常量池对象的副本
*/
String s = "abc";
String str = new String("abc"); //创建了2个对象
System.out.println(s == str);
}
private static void demo()
{
/**
* String是有常量池的,当我们创建对象的时候,他会首先到常量池中去查找
* 如果查找到了则返回该常量池的地址
* 如果没有查找到,先创建该对象,然后将该对象放入常量池中
*/
String str = "abc";
String str1 = "abc";//创建了一个对象
System.out.println(str == str1);
System.out.println(str.equals(str1));
}
}
问题描述
-
string创建对象问题字符串常量池问题
-
String a=new String("aaaa")如果之前常量池没有aaaa字符串,那么这句代码具体创建的是几个对象?,
解决方案
string是比较特殊的。
new String就好比开了一个空间里面装着aaa而且有了自己的地址符。也就是说是一个对象了。
而String a也是一个对象,你要记得每个类型都有默认值的,但是后面的等于号是将new String的地址符给了a,这时a也指向那个空间,于是它的值也是aaa.
其实在工作编程中是不用这么计较的,用一个定义一个就好。
String是类型,也就是说它有默认值,你记得这一点就行了。只不过它也可以像实例化对象一样赋值。
希望回答对你有帮助
String 要看是怎么赋值的
1.String str = new String("aaaaa");这样通过new 关键字实例化的 内存中会重新分配一个空间 如果还有一个String str2 = new String("aaaaa"); 仍旧是重新分配空间。
两个虽然都是“aaaaa”但是指向不同的地址。这和普通了没什么区别
2.String str3 = "aaaaa";这样赋值的话,你可以这样理解:把“aaaaa”这个常量赋值给str3,就是指向常量的地址。所以str4=“aaaaa”;则str3和str4都指向该常量的地址。
一个对象,变量a是对象的引用
解决方案四:创建了两个对象,一个对象存在于堆内存中,还有一个对象存在于常量池中,堆中对象的值就是指向常量池中的地址的。
解决方案五: String a=new String("aaaa"),当这个主线程没有走完的时候,创建这个a对象它会先在栈内存中创建一个a对象,之后会去常量池中查看是否有个String类型的aaaa,如果没有,就会创建一个,如果有的话,就会直接使用这个值,但要注意,你这里用了一个new关键字,这时候,它会在把常量池里面的aaaa值重新复制一遍到堆里面去,这时候又在堆里面创建了一个对象。因此应该有2个或3个对象。
String a = "aaaa";
String b = "aaaa";
String c = new String("aaaa");
System.out.println(a==b);
System.out.println(a==c);
打印出来的结果就是a,b都是用的常量池里面的aaaa对象,地址相同。a,c中a用的是常量池里面的aaaa地址,c用的是复制的aaaa放在堆中的地址,因此地址不同,所以答案是true,false。
如果常量池没有"aaaa"字符串,那么通过new关键字来创建一个String时,创建的会是两个对象。
在执行String a=new String("aaaa")时,首先会在String池中创建一个可共享的字符串对象;然后通过new关键字,在内存中会创建一个包含了"aaaa"的String对象
解决方案七: 两个
String a=new String("aaaa");
第一步会在堆中创建一个String对象,这是使用new关键字的必然结果。
第二步会在字符串池中也创建一个String对象。
e) 源码
i. 给你一个字符串然后在不带用任何API方法的基础上完成替换某些字符的功能
package wbl.test;
public class tiHuan
{
public static void main(String[] args)
{
String string=replace("adadafdfadfas", "asd");
System.out.println(string);
}
public static String replace(String string,String string2)//将string中所有与string2相同的字符替换为A
{
char[] c1=string.toCharArray();//将字符串转换为char数组
if(string != null && string2 != null)
{
char[] c2=string2.toCharArray();
for (int i = 0; i < c1.length; i++) {
for (int j = 0; j < c2.length; j++) {
if(c1[i]==c2[j])
c1[i]='A';
}
}
}
return new String(c1);
}
}
ii. 给一个字符串,要实现字符串的反转,然后排序(反转和排序的结果都要保存下来)
public class fanZhuan
{
public static void main(String[] args)
{
String string=new String("qweasadzxcrf");
fanzhuan(string);
paixu(string);
}
/**
* 将字符串从小到大排序
*/
private static void paixu(String string)
{
System.out.println();
char[] cs=string.toCharArray();
char c='0';
for(int i=0;i<cs.length-1;i++)//最后一个不需要比较
{
for(int j=i;j<cs.length;j++)
{
if(cs[i]>cs[j])
{
c=cs[i];
cs[i]=cs[j];
cs[j]=c;
}
}
}
System.out.print("排序前:");
System.out.println(string);
System.out.print("排序后:");
System.out.println(new String().valueOf(cs));//将char数组转换为字符串
}
/**
*
*/
private static void fanzhuan(String string)
{
char[] cs=string.toCharArray();
char c='0';
for(int j=0;j<cs.length/2;j++)
{
c=cs[j];
cs[j]=cs[cs.length-j-1];
cs[cs.length-j-1]=c;
}
System.out.print("反转前:");
System.out.println(string);
System.out.println(new String().valueOf(cs));
}
}