1.局部变量和成员变量的区别1)书写位置不同
局部变量:在方法定义中或者方法声明上
成员变量:在类中,方法外
2)内置位置不同
局部变量:在栈内存中
成员变量:在堆内存中
3)生命周期不同
局部变量:随着方法的调用而存在,随着方法调用结束而消失
成员变量:随着对象的创建而存在,随着对象的创建完毕等待垃圾回收器回收而消失
4)初始化不同
局部变量:在使用之前必须初始化; (要么先定义,然后在初始化;或者直接初始化)
成员变量:可以不初始化,系统会默认的赋值
2.静态变量和成员变量的区别1)存储数据内存位置不同
静态变量:方法区中的静态区域(共享内存)
成员变量:堆中
2)别名不同
静态变量:"类成员"
成员变量:对象的特有属性(实例变量)
3)生命周期不同:
静态变量:随着类的加载而加载,随着类的加载完毕而结束(消失),类加载一次,静态的随着加载一次
成员变量:随着对象的创建而存在,随着对象的创建完毕等待垃圾回收器回收而消失
4)调用方式不同
静态变量:既可以使用对象名访问,也可以使用类名访问(推荐后者这种方式)
成员变量:只能通过该对象名访问!
3.继承的好处和特点
好处:
1)提高代码复用性
2)提高代码维护性
3)类与类之间的继承关系,是多态的条件
特点:
1)类与类之间的关系只支持单继承,不支持多继承!
2)但是可以多层继承,不停的可以往上继承...
4.继承中,成员变量子父类名称一致,如何访问
子类继承父类,成员变量名称一致:
就近原则
1)首先在子类的局部位置找,是否存在这个变量,存在就使用
2)如果不存在,在子类的成员位置找,存在,就使用
3)如果还不存在,在父类的成员位置找,存在,就使用
4)如果也不存在,(已经顶层父类),报错,说明不存在这个变量
5.继承中,子类如何访问父类的构造方法?如果父类中没有给出无参构造,如何解决?
子类继承父类,不能继承父类的构造方法,但是可以通过super关键字间接访问父类的构造方法
子类继承父类,子类的所有构造方法都会默认的访问父类的无参构造方法
如果父类中没有给出无参构造方法,子类构造方法全部报错,解决方案
1)手动给出无参构造方法:最直接的方式
2)可以通过直接访问父类的有参构造方法super(xx)
3)了解:子类中的所有构造方法中的某一个只要能够让父类初始化即可,
在子类的有参构造方法中通过this();访问本类的无参构造方法
在通过本类的无参构造方法里面 super(xx); 访问父类的有参构造方法
1.什么是多态?多态的前提条件
一个事物体现出的不同形态,内存的变化;
前提条件:
1)需要存在继承关系
2)存在方法重写,子类继承父类,将部分功能进行重写
3)必须存在:父类引用指向子类对象:向上转型
格式:
父类名 对象名 = new 子类名() ;
2.多态的成员访问特点
成员访问特点:
父类名 对象名 = new 子类名() ;
成员变量:
编译看左,运行看左!
成员方法:
编译看左,运行看右;因为存在方法重写,所以子类的功能将父类的功能覆盖了
静态方法:
编译看左,运行看左; 它不属于方法重写,静态的东西是和类相关的,直接使用类名访问
构造方法:
无参/有参,子类继承父类,需要让父类初始化,因为子类可能会用到父类的数据,然后再是子类初始化!(分层初始化)
3.多态的好处和弊端?如何解决
好处: 1)提高代码的复用性(由继承保证) 2)提高代码的扩展性(由多态保证:父类引用指向子类对象) 弊端: 不能使用子类的特有功能 解决方案: 1)直接手动创建子类本身对象:子类名 对象名 = new 子类名() ;,它比较消耗内存空间,需要new 2)向下转型:将父类的引用强制转换为子类的引用,前提必须向上转型 子类名 对象名 = (子类名)父类引用;
4.什么抽象类? 如何实例化呢?
如果一个类中有抽象方法,那么这个类定义为抽象类(abstract class XX) (描述现实世界的概括性的事物 人,动物,形状,...) 抽象类不能直接实例化,但是可以通过具体的子类进行实例化,抽象类多态; 抽象的父类名 对象名 = new 具体的子类名() ;
5.什么是接口,接口的定义格式以及和子实现类之间的关系
在Java语言中,接口体现出的一种提供的事物的"额外功能",并不是类,理解为"所有抽象方法的集合"
接口的抽象方法只能被实现,定义格式
interface 接口名{}
interface Inter{
public abstract void show() ;
}
implements:实现关系
class InterImpl implements Inter{
public void show() {
//重写方法
}
}
接口也不能实例化
如何实例化:"接口多态"
接口名 对象名 = new 子实现类名() ;
6.abstract和哪些关键字冲突
abstract和
private:被private修饰的方法只能在当前类中访问
static:被类名访问,将某个方法定义为抽象方法,需要被子类实现(重写),需要通过对象名来访问
final:被final修饰的成员方法不能被重写,而abstract修饰的方法,强制子类必须重写抽象方法!
修饰类:抽象类
修饰方法:抽象方法
public abstract 返回值类型 方法名(形式参数列表) ;
1.面向对象三大特征之继承: 什么时候使用继承?
如果B类是A类的一种,或者A类是B类一种,这个时候就可以使用继承
继承的体系的是一种"is a"的关系!
伪代码:
class A{
public void show(){}
public void show2(){}
}
class B{
public void show2(){}
public void show3(){}
}
发现:A类B类都存在show2()方法
定义B类的时候,直接继承自A类
优化之后:
class B extends A{
public void show3(){}
}
这种方式不好,开发中慎用!
不能为了使用部分功能,而是使用继承,因为B类继承自A类,可以将show2()方法继承过来,但是A类中其他成员方法B类可能不需要, 继承的本身弊端:具有局限性!
2.接口中的成员特点:(重要)
1、接口中可以定义变量,但是变量必须有固定的修饰符修饰,public static final 所以接口中的变量也称之为常量,其值不能改变。后面我们会讲解static与final关键字
2、接口中可以定义方法,方法也有固定的修饰符,public abstract
3、接口不可以创建对象。
4、子类必须覆盖掉接口中所有的抽象方法后,子类才可以实例化。否则子类是一个抽象类。
interface Demo { ///定义一个名称为Demo的接口。
public static final int NUM = 3;// NUM的值不能改变
public abstract void show1();
public abstract void show2();
}
//定义子类去覆盖接口中的方法。类与接口之间的关系是 实现。通过 关键字 implements
class DemoImpl implements Demo { //子类实现Demo接口。
//重写接口中的方法。
public void show1(){}
public void show2(){}
}
3.接口和抽象类有什么区别?
1)成员区别 接口: 成员变量:只能是常量,存在默认修饰符 public static final 可以省略 成员方法:只能是抽象方法,存在默认修饰符 public abstract 可以省略 构造方法:接口没有 抽象类: 成员变量:即可以是常量,也可以是变量 成员方法:既可以存在抽象方法,而且抽象方法abstract不能省略,也可以存在非抽象方法\ 构造方法:存在:无参/有参,继承关系, 先让父类初始化,然后在是子类初始化(分层初始化) 2)关系的区别 类与类之间关系:继承关系 extends 只支持单继承,不支持多继承,但可以多层继承 类与接口之间的关系:实现关系 implements 一个类继承另一个类的同时,可以实现多个接口 接口与接口之间关系:继承关系 extends 不仅支持单继承,也可以多继承,也可以多层继承!
1.带包的编译和运行 (手动和自动 分别dos控制台使用)
带包的编译和运行 (手动和自动 分别dos控制台使用)
在同一包下:
首先:创建package包名(推荐多级包:中间点隔开,分包)
两种情况:
1)手动方式:
a)将你当前的多级包名创建出来
b)先将当前的Java文件进行编译
在当前目录中:使用javac java源文件 ---->.class文件
c)将当前字节码文件存储在刚才1)包下
d)带包进行运行
java 包名.类名
D:\EE_2110\day15\code\01_同一个包下的编译和运行>javac Demo.java
D:\EE_2110\day15\code\01_同一个包下的编译和运行>java com.qf.Demo
demo...
D:\EE_2110\day15\code\01_同一个包下的编译和运行>
2)自动方式:
a)对Java文件进行编译
javac -d . 某个Java文件 ---->自动的产生包名和字节码文件
b)带包进行运行
java 包名.类名
D:\EE_2110\day15\code\01_同一个包下的编译和运行>javac -d . Demo.java
D:\EE_2110\day15\code\01_同一个包下的编译和运行>java com.qf.Demo
demo...
D:\EE_2110\day15\code\01_同一个包下的编译和运行>
2.内部类---了解 (最终以后翻阅原码:能看懂类的组成结构...)
成员内部类
静态的成员内部类访问方式
局部内部类
面试题(重点):局部内部类的一道描述题
一.内部类的另一种格式:(重点)
-
匿名内部类:没有名字的类
-
格式:
-
new 类名/接口名(){ 一般类名--->抽象类
-
重写抽象方法(){
-
业务功能;
-
}
-
} ;
-
匿名内部类的本质:
-
就是继承了该抽象类或者实现了该接口子类对象; *
-
应用场景:
-
匿名内部类的使用在方法定义中或者是方法声明上:局部位置中使用
-
public void show(抽象类名 参数名){
-
}
-
1)可能方法的形式参数是一个接口/抽象类
-
2)可能方法返回值类型时一个接口/抽象类
二.成员内部类中的修饰符:
-
可以private,static *
-
private: 保证数据安全性(将内部类隐藏了)
-
举例:
-
身体内有心脏;
-
伪代码
-
class Body{
-
//成员内部类
-
private class Heart{
-
//成员方法
-
//并不是所有的人都可以直接完成这个完成手术---不安全!
-
public void operator(){
-
System.out.println("心脏出问题了,需要做心脏搭桥手术...") ;
-
}
-
}
-
} *
-
//测试类中直接访问Heart里面operartor
-
外部类名.内部类名 对象名 = 外部类对象.内部类对象; *
-
//Body.Heart bh = new Body().new Heart() ;
-
// bh .operator() ; * *
-
成员内部类里面还可能存在静态修饰符static *
-
静态的成员内部类中的成员方法(静态的还是非静态),访问外部类的成员变量,都必须是静态的 *
-
1)静态的成员内部类随着外部类的加载而加载;
-
2)如何直接访问静态的成员内部类的中成员方法
-
外部类名.内部类名 对象名 = new 外部类名.内部类名() ; *
-
三.局部内部类的也是内部类的一种 *
-
特点:
-
局部内部类可以访问外部类的成员吗?
-
可以,包括私有; *
-
面试题:
-
局部内部类访问局部变量的时候,有什么要求?为什么?
-
要求当前的局部变量为常量:加入final修饰 ,为什么
-
jdk8 jvm已经做了内存优化:通过反编译工具查看:num2:自动带上final修饰(默认,省略了)
-
jdk7以前(包含jdk7):局部内部类访问局部变量,前面必须显示的加入final修饰 *
-
局部变量的生命周期随着方法的调用而存在,随着方法调用结束而消失;
-
但是局部变量还在被局部内部类的成员方法在使用,局部类的对象不会立即消失,需要等待GC回收,需要将这个变量变成
-
常量,保证一直可以访问到!
3.案例
-
看程序,补全代码---要求在控制台输出"helloword"
-
考点:
-
匿名内部类的使用----方法 返回值是如果是接口,需要接口的子实现类对象(匿名内部类的方式)
-
静态方法访问方法:类名方法 / interface Inter{ void show() ; } class Outer{ //补全代码 //... public static Inter method(){ / return //Jdk8以后新特性:lambda表达式:接口中如果只有一个抽象方法,就可以使用函数式接口,使用-> () -> System.out.println("helloworld") ;*/ return new Inter() { @Override public void show() { System.out.println("helloworld"); } }; } } public class Test { public static void main(String[] args) { //给定的代码为 Outer.method().show();
//Outer.method() ;这个方法是静态方法 //继续Outer.method().show()----->Outer.method()不仅是静态的而且存在返回值,能够调用show方法,返回就是接口的子类对象
}
4.常用类
重点类 Object Scanner:提供判断 String 一些功能(重点) StringBuffer 功能 Jdk5以后的新特性:自动拆装箱: 基本数据类型:----- 包装类类型(引用类型) 整数类型 int Integer :内部缓存区内部类:IntegerCache (范围 -128-127) :面试题 字符类型 char Character:判断功能
Calendar:日历类 获取日历的年份,月份,月份中的日期,小时,分钟,描述... Date:java.util.Date;精确到毫秒值的日期格式 网页----注册---输入用户名的出生日期 "1990-8-30" java.sql.Date;日期类型 其他类 • System • gc() :手动开启垃圾回收器 • finalize():和GC有关系 • 复制数组 • 获取当前系统时间毫米数 • 小数精确计算 • BigDecimal • Math:数学运算类 • Random:获取随机数的类(随机数生成器) • nextInt():取值:int类型的范围 • nextInt(int n)
1.Object类的其他功能
1)public String toString()返回对象的字符串表示形式;应该是一个简明扼要的表达,容易让人阅读 * 创建对象,输出对象名称:打印出来的对象的地址值,没有意义; * 应该看到的是当前这个对象的成员信息表达式! * * * 建议所有子类覆盖此方法。 * * * Integer类 * int类型包装类类型 * 静态功能: * public static String toHexString(int code) 2)public boolean equals(Object obj):指示其他对象与此对象是否"相等" * * * ==和equals的区别: * ==:连接的是基本数据类型:比较的基本数据类型数据值是否相等 * int a= 10 ; * int b = 20 ; * a==b ; * * ==:连接的是引用数据类型,比较的是引用数据类型的地址值是否相同 * * equals:默认比较的是地址值是否相同,建议子类重写equals方法,比较他们内容是否相同(成员信息是否相同) * * 在重写equals方法的同时,还需要重写hashCode()方法,保证哈希码值必须一样,才能比较equals * * alt+ins--->equals and hashCode * 如果重写Object类的equals方法之后,都是比较的内容是否相同(成员信息是否相同) * * 大部分的常用类都会重写Object类的equals方法 3)protected Object clone() throws CloneNotSupportedException:调用过程中可能存在克隆不支持的异常 * * 对于jdk提供的类的方法本身存在异常.谁调用这个方法,必须做出处理,否则报错,最简单的方式继续往上抛 throws * * 创建并返回此对象的副本(浅克隆) :了解 * * 简单理解:复制对象,获取对象的成员...
2.Scanner类的判断功能
1)Scanner:java.util的类:文本扫描器 * 一直在用这个:录入录入数据 * 构造方法 * public Scanner(InputStream source) * * 成员方法: * 判断功能 haxNextXXX():判断下一个录入都是是否是XXX类型 * public boolean hasNextInt(): * public boolean hasNextLine(). * * 获取功能 nextXXX() * public int nextInt() * public String nextLine() * public String next() * ... 例子: public class ScannerDemo { public static void main(String[] args) { //public Scanner(InputStream source):形式参数时候一个抽象类,需要有子类对象 //System类中存在一个"标准输入流"in //public static final InputStream in InputStream inputStream = System.in ; //字节输入流 //创建键盘录入对象 Scanner sc = new Scanner(inputStream) ; System.out.println("录入一个数据:"); /* int num = sc.nextInt(); //获取功能 System.out.println(num);*/ //java.util.InputMismatchException:录入的数据和需要接收的num类型不匹配 //Scanner类的提供的判断功能 if(sc.hasNextInt()){ //录入的int类型 //接收int int num = sc.nextInt() ; System.out.println("您输入的数据是:"+num); }else if(sc.hasNextLine()){ //录入的String String line = sc.nextLine() ; System.out.println("您输入的数据是:"+line); }else{ System.out.println("对不起,没有提供其他接收的类型值..."); } } }
3.String: /StringBuffer重点类 :互相转换
String的描述
* String类代表字符串。
* 'Java程序中的所有字符串文字(例如"abc" )都被实现为此类的实例。 "字符串本身就是常量"
* String的特点:
* 字符串不变的; 它们的值在创建后不能被更改
* 推荐方式:
* String 变量名 = "字符串常量" ;
*
* 知道:构造方法有哪些
* public String():无参构造
* String(byte[] bytes):将字节数组可以构造字符串对象
* public String(byte[] bytes,int offset,int length)一部分字节数组构造成字符串对象
* public String(char[] value):将字符数组构造成字符串对象
* public String(char[] value, int offset,int count):将一部分字符数组构造成字符串对象
* public String(String original):创建一个字符串对象,里面存储字符串常量
*
* 面试题:
* 数组中有没有length(),字符串String类中有没有length(),集合中有没有length()?
* 没有length(),只有length属性
*
* String:有
* 集合:没有----获取长度:size()
* public int length():获取字符串长度
*
*
* null :空值 :没有对象 引用数据类型的默认值
* String s = null ;
* String s = "" ; 空字符序列,有,是空的,存在对象!
* // String s = new String("") ;
*/
public class StringDemo {
public static void main(String[] args) {
//构造方法测试
// public String():无参构造
String s1 = new String() ;
System.out.println("s1:"+s1) ;
System.out.println(s1.length()) ;
System.out.println("---------------------------------------") ;
//String(byte[] bytes):将字节数组可以构造字符串对象
//创建一个字节数组
byte[] bytes = { 97,98,99,100,101} ;
String s2 = new String(bytes) ; //字符串底层有字符序列:字符数组----将97 寻找ASCII码表的字符内容
System.out.println("s2:"+s2);
System.out.println(s2.length());
System.out.println("---------------------------------------") ;
// public String(byte[] bytes,int offset,int length)一部分字节数组构造成字符串对象
//参数1:字节数组对象,参数2:起始索引 参数3:指定长度
String s3 = new String(bytes,1,3) ;
System.out.println("s3:"+s3) ;
System.out.println(s3.length());
System.out.println("---------------------------------------") ;
//public String(char[] value):将字符数组构造成字符串对象
//创建一个字符串数组
char[] chs = {'h','e','l','l','o','高','圆','圆'} ;
String s4 = new String(chs) ;
System.out.println("s4:"+s4) ;
System.out.println(s4.length());
System.out.println("---------------------------------------") ;
//public String(char[] value, int offset,int count):将一部分字符数组构造成字符串对象
String s5 = new String(chs,5,3) ;
System.out.println("s5:"+s5) ;
System.out.println(s5.length());
System.out.println("---------------------------------------") ;
//public String(String original):创建一个字符串对象,里面存储字符串常量
String s6 = new String("hello") ;
System.out.println("s6:"+s6);
System.out.println(s6.length());
/* String s7 = "hello" ;
System.out.println("s7:"+s7);
System.out.println(s7.length());*/
}
}
字符串的特点:
* 字符串不变的; 它们的值在创建后不能被更改
*
* 值:常量地址值...
*
* 字符串是常量:在内存中:方法区中的常量池中存储(池化技术...)
*
*
* 面试题:
* String s = "hello" ;
* 和
* String s2 = new String("hello") ;两个有什么区别,分别创建了几个对象!
*
* 共同点:都是在创建一个字符串对象"hello"
* 但是内存执行不一样
* 前者:只是在常量池中开辟空间,创建一个对象 :推荐这种方式,节省内存空间!
* 后者:在堆中开辟空间,而且里面存在常量----常量池中标记 ,创建两个对象
*
*
*/
public class StringDemo2 {
public static void main(String[] args) {
String s1 = "hello" ; //创建一个字符串对象
String s2 = new String("hello") ;
System.out.println(s1 == s2) ;
System.out.println(s1.equals(s2)) ;
//String已经重写了Object的equals方法:默认比较就不是地址值而是内容是否相同
}
}
String类的获取功能:
* char charAt(int index) :获取指定索引出的字符值
* public String concat(String str):拼接功能:拼接新的字符串
* public int indexOf(int ch):返回指定字符第一次出现的字符串内的索引
* int lastIndexOf(int ch) :查询指定字符最后一次出现的索引值
* int length() :获取字符串长度
* public String[] split(String regex):字符串的拆分方法:返回的字符串数组 (重要)
*
*
* String substring(int beginIndex) :字符串截取功能 (重要)
* 默认从beginIndex起始索引截取到末尾
* public String substring(int beginIndex,int endIndex) :从指定位置开始截取到指定位置结束(包前不包后)
* 包含beginIndex位置,不包含endIndex位置,包含到endIndex-1
*/
public class StringDemo {
public static void main(String[] args) {
//测试
//创建一个字符串
String s = "helloworldJavaEE" ;
// char charAt(int index) :获取指定索引出的字符值
System.out.println("charAt():"+s.charAt(4)) ;
System.out.println("--------------------------------------") ;
// public String concat(String str):拼接功能:拼接新的字符串
System.out.println("concat():"+s.concat("Android")) ;//拼接功能
System.out.println(s+"IOS");//拼接符号
System.out.println("---------------------------------------") ;
// public int indexOf(int ch):返回指定字符第一次出现的字符串内的索引
//参数为字符/或int: int的值也可以找ASCII码表的字符
System.out.println("indexOf():"+s.indexOf('l'));
//int lastIndexOf(int ch) :查询指定字符最后一次出现的索引值
System.out.println("lastIndexOf():"+s.lastIndexOf('l'));
System.out.println("---------------------------------------") ;
// public String[] split(String regex):字符串的拆分方法:返回的字符串数组 (经常用到)
//参数可以是正则表达式或则普通字符串---分割符号
//创建一个新的字符串对象
String str = "Java-Php-Go-R-Python-C-C++-C#-Net" ;
String[] strArray = str.split("-") ;
for(int x = 0 ; x < strArray.length ; x++){
System.out.print(strArray[x]+" ");
}
System.out.println();
System.out.println("---------------------------------------") ;
//截取:
/**
* String substring(int beginIndex) :字符串截取功能 (重要)
* 默认从beginIndex起始索引截取到末尾
* public String substring(int beginIndex,int endIndex) :从指定位置开始截取到指定位置结束(包前不包后)
* 包含beginIndex位置,不包含endIndex位置,包含到endIndex-1
*/
System.out.println("subString():"+s.substring(5));
System.out.println("subString():"+s.substring(5,10));
}
}
String类的转换功能:
*
* public char[] toCharArray():将字符串转换字符数组
* byte[] getBytes() :使用平台的默认字符集进行编码过程:将字符串--->字节数组
* byte[] getBytes(String charset):使用指定的字符集进行编码 "GBK/UTF-8"
* 编码和解码
* 编码:将能看懂的字符串---->看不懂的字节
* 解码:将看不懂的字节----->能看懂的字符串
*
* public String toLowerCase():将字符串中的每一个字符转换成小写
* public String toUpperCase():将字符串中的每一个字符转换成大写
* static String valueOf(boolean b/float/long/double/int/char /....Object)
* 万能方法:
* 将任意的数据类型转换成String :静态的功能
*
*
*/
public class StringDemo2 {
public static void main(String[] args) {
//有一个字符串
String s = "helloworld" ;
//public char[] toCharArray():将字符串转换字符数组
char[] chs = s.toCharArray();
for (int i = 0; i < chs.length; i++) {
System.out.println(chs[i]);
}
System.out.println("---------------------------------------------") ;
// byte[] getBytes() :使用平台的默认字符集进行编码过程:将字符串--->字节数组
byte[] bytes = s.getBytes() ;
// System.out.println(bytes);
//看到字节数组的内容: 使用数组工具Arrays
//static String toString(任何类型的数组) :静态功能---将任何类型的数组转换成字符串形式
System.out.println(Arrays.toString(bytes));
//[104, 101, 108, 108, 111, 119, 111, 114, 108, 100] :英文:寻找它的ASCII码表
System.out.println("---------------------------------------------") ;
//public String toLowerCase():将字符串中的每一个字符转换成小写
//public String toUpperCase():将字符串中的每一个字符转换成大写
System.out.println(s.toLowerCase());
System.out.println(s.toUpperCase());
System.out.println("---------------------------------------------") ;
/**
* static String valueOf(boolean b/float/long/double/int/char /....Object)
* 万能方法:
* 将任意的数据类型转换成String :静态的功能
*/
int i = 100 ;//int
String result = String.valueOf(i);
System.out.println(result) ;//数字字符串 "100"
}
}
String的判断功能
* public boolean contains(String s):判断是否包含子字符串
* public boolean startsWith(String prefix):判断是以指定的字符串开头
* public boolean endsWith(String suffix):判断是是以指定的字符串结尾
* boolean equals(Object anObject) :判断字符串内容是相等:区分大小写
* boolean equalsIgnoreCase(String anotherString) :判断字符串内容是否相等,忽略大小写
* public boolean isEmpty():判断字符串是否为空
*
*/
public class StringDemo {
public static void main(String[] args) {
//String字符串
String s = "helloJavaee" ;
// public boolean contains(String s):判断是否包含子字符串
System.out.println("contains():"+s.contains("hel"));
System.out.println("contains():"+s.contains("ak47"));
// public boolean startsWith(String prefix):判断是以指定的字符串开头
// public boolean endsWith(String suffix):判断是是以指定的字符串结尾
System.out.println("-----------------------------------------------") ;
System.out.println(s.startsWith("hel"));
System.out.println(s.startsWith("高圆圆"));
System.out.println(s.endsWith("ee"));
System.out.println(s.endsWith("wor"));
System.out.println("-----------------------------------------------") ;
String s2 = "helloJavaEE" ;
System.out.println(s.equals(s2)) ; //区分大小写
//boolean equalsIgnoreCase(String anotherString)
System.out.println(s.equalsIgnoreCase(s2));//不区分大小写
s = "" ;
System.out.println(s.isEmpty());
}
}
1.String,作为形式参数传递,有什么特点
1)String类型作为形式参数和基本类型作为形式的效果一样
2)形式参数的改变不会直接影响实际参数,String类型特殊的引用类型!
3)其他引用数据类型,形式参数的改变会直接影响实际参数!
例子:public class StringTest {
public static void main(String[] args) {
String s1 = "helloworld" ;
System.out.println(s1) ;
change(s1) ;
System.out.println(s1) ;
System.out.println("----------------------------------") ;
int a = 10 ;
int b = 20 ;
System.out.println("a:"+a+",b:"+b);
change(a,b) ;
System.out.println("a:"+a+",b:"+b);
}
public static void change(int a,int b){
System.out.println("a:"+a+",b:"+b);
a = b ;
b = a+ b ;
System.out.println("a:"+a+",b:"+b);
}
private static void change(String s1) {//String类型作为形式参数
System.out.println(s1) ;
s1+="javaEE" ;
System.out.println(s1) ;
}
}
2.String的其他功能
String类的其他功能
* public String replace(char oldChar,char newChar):将新的字符值把旧的字符替换掉
* public String replace(String oldChar,String newChar):将新的字符串值把旧的字符串替换掉
*public String replaceAll(String regex,String replacement):使用指定的replacement替换的字符串内容
* 将符号正则表达式的匹配的字符串替换掉 (用到正则表达式使用)
* 参数1:正则表达式 举例: [0-9]
*
* public String trim():去除字符串前后两端空格
* 一般用在:IO中传输文件(读写文件)
*
* 面试题: 考源码
* public int compareTo(String anotherString) :如何进行字典比较
* String s1 = "hel" ;
* String s2 = "hello" ;
* 结果是多少,为什么这个值?
*/
public class StringDemo {
public static void main(String[] args) {
//public String replace(char oldChar,char newChar):将新的字符值把旧的字符串替换掉,返回的新的自测
String s = "helloworld" ;
System.out.println("replace():"+s.replace('l','k')) ;
System.out.println("replace():"+s.replace("world","高圆圆"));
System.out.println("--------------------------------------------------") ;
//public String trim():去除字符串前后两端空格 (IO流中,上传文件:保证读取文件内容,先去除两端空格)
String s2 = " javaEE " ;
System.out.println("s2:"+"-----"+s2+"-----");
System.out.println("-------------------------------------") ;
System.out.println("s2:"+"-----"+s2.trim()+"-----");
}
}
3.String的应用
遍历
将int类型数组---->String类型
字符串的反转
录入一个字符串,统计大写字母字符,小写字母字符,数字字符个数 不考虑特殊字符
"HElloWorld123JavaEE456"
判断一个字符串是否是对称字符串
abmba
aba
...
"woaijavawohenaijavawofeichangaijavazhendefeichangaijava"
"java"---统计大串中的次数
/*反转字符串
*思路:字符串变数组,然后数组反转,再将数组变字符串
**/
public static String reverseString(String s){
char[] chs = s.toCharArray(); //字符串变数组
reverse(chs); //数组反转
return new String(chs); //数组变字符串
}
public static void reverse(char[] chs){
int start=0;
int end = chs.length-1;
for(; start<end; start++,end--){
swap(chs, start, end);
}
}
public static void swap(char[] chs, int start, int end){
char temp = chs[start];
chs[start] = chs[end];
chs[end] = temp;
}
字符串出现次数:
/*字符串key在str中出现的次数
*利用indexOf来查找,找到后用substring截取后续部分继续查找
**/
public static int getSubCount(String str, String key){
int count = 0;
int index = 0;
while( (index=str.indexOf(key)) != -1 ){
str = str.substring(index+key.length());
count++;
}
return count;
}
4.StringBuffer /Date类 /Integer/Character
StringBuffer:
* 添加字符序列
* StringBuffer append(任何数据类型):将任何数据类型的数据追加字符序列中(字符串缓冲区)
* StringBuffer insert(int offset, String str) :插入元素:在指定位置插入指定的元素
*
* 删除:
* public StringBuffer deleteCharAt(int index):在指定的位置处删除的指定的字符,返回字符串缓冲区本身
* public StringBuffer delete(int start,int end):删除指定的字符从指定位置开始,到end-1处结束
*/
public class StringBufferDemo2 {
public static void main(String[] args) {
//创建一个字符串缓冲区对象
StringBuffer sb = new StringBuffer() ;
System.out.println("sb:"+sb);
// StringBuffer append(任何数据类型):将任何数据类型的数据追加字符序列中(字符串缓冲区)
/* StringBuffer sb2 = sb.append("hello");
StringBuffer sb3 = sb2.append('A');
StringBuffer sb4 = sb3.append(12.56);
StringBuffer result = sb4.append(100);
System.out.println(result);*/
sb.append("hello");
sb.append("world") ;
sb.append("javaee") ;
/* sb.append('A');
sb.append(true) ;
sb.append(13.45) ;
sb.append(100) ;
sb.append(new Object()) ;
System.out.println("sb:"+sb);*/
System.out.println("sb:"+sb) ;
// StringBuffer insert(int offset, String str)
sb.insert(5,"高圆圆") ;
System.out.println("sb:"+sb);
//hello高圆圆worldjavaee
System.out.println("----------------------------------------------------------") ;
// public StringBuffer deleteCharAt(int index)
//需求:删除第一个e字符
System.out.println(sb.deleteCharAt(1));
//需求:删除第一个l字符
System.out.println(sb.deleteCharAt(1));
//public StringBuffer delete(int start,int end)
System.out.println(sb.delete(3,7));
}
}
StringBuffer: 简称"字符串缓冲",线程安全的,而且可变的字符序列!
*
* 线程: -----多线程:Thread
* 单线程 :程序的执行路径只有一条 ,不考虑安全性,只考虑效率!
* 多线程 :程序的执行路径有多条,考虑安全性,效率问题不是重点!
*
*
* 面试题:StringBuffer和StringBuilder有什么区别?
* 共同点:两者都是字符串区,支持可变的字符序列,而且都有互相兼容的API(功能相同的)
* 不同点:
* 前者:线程安全的类,多线程环境下使用居多-----同步(安全)----->执行效率低
* 银行的网站/医疗网站
* 后者:线程不安全的类,单线程程序中使用居多---->不同步(不安全)----->执行效率高\
* 论坛的网站...
*
* StringBuffer的构造方法
* StringBuffer();无参构造方法 :使用居多
* StringBuffer(int capacity):指定容量大小的字符串缓冲区
* StringBuffer(String str) :指定缓冲区的具体内容str,容量大小=16个默认容量+当前字符串长度
*
* public int length()获取字符缓冲区中的长度
* public int capacity():获取字符串缓冲区中的容量大小
*/
public class StringBufferDemo{
public static void main(String[] args) {
// StringBuffer();无参构造方法
//创建一个字符串缓冲区对象
StringBuffer sb = new StringBuffer() ; //默认的初始化容量16个(足够用了)
System.out.println("sb:"+sb) ;
System.out.println(sb.length()) ;
System.out.println(sb.capacity()) ;
System.out.println("-------------------------") ;
// StringBuffer(int capacity):指定容量大小的字符串缓冲区
StringBuffer sb2 = new StringBuffer(50) ;
System.out.println("sb2:"+sb2);
System.out.println(sb2.length());
System.out.println(sb2.capacity());
System.out.println("-------------------------") ;
// StringBuffer(String str) :
String s = "helloworld" ;
StringBuffer sb3 = new StringBuffer(s) ;
System.out.println("sb3:"+sb3);
System.out.println(sb3.length() );
System.out.println(sb3.capacity() );
//StringBuffer sb4 = "hello" ; //不能这样写
/* String str = "hello" ;
StringBuffer sb4 = str ;*/
}
}
String和StringBuffer有什么区别?
*
* 前者: String是常量,一旦被赋值,其值不能被更改;它的不可变的字符序列
* 开发中:前端提交后台的数据--------> String (它的功能远远大于StringBuffer)
* 作为形式参数,形式参数的改变不会影响实际参数,特殊的引用类型,和基本数据类型作为形式参数的效果一样
*
* 后者: StringBuffer是可变的字符序列,线程安全的类,同步,执行效率低,单线程程序中的使用StringBuilder替代StringBuffer
* 字符串缓冲区 里面存储的字符序列-------> 还需要转换成String类型
* 作为形式参数,形式参数的改变会直接影响实际参数!
*
*
* StringBuufer的场景: 键盘录入一个数据:"ababababacsdfsdfsdfsdfdfbbbbbbdccccdddfffggg",排序
* a(多少个)b(多少个)
*/
public class StringBufferTest2 {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("helloworld") ;
System.out.println("sb:"+sb) ;
change(sb) ;
System.out.println("sb:"+sb) ;
int[] arr = {1,2,3,4,5} ;
System.out.println(arr[1]) ;
change(arr) ;
System.out.println(arr[1]);
}
public static void change(int[] arr){
for (int x = 0 ; x < arr.length; x++){
if(arr[x] % 2== 0){
arr[x] = arr[x]*=2 ;
}
}
}
private static void change(StringBuffer sb) {//作为形式参数
System.out.println("sb:"+sb) ;
sb.append("qianfeng") ; //通过对象在追加内容:改变字符序列....
System.out.println("sb:"+sb) ;
}
}
开发中:引用类型
* 有可能将A类型转换成B类型,结果最终需要的是B类型
*
* 有的时候,A类型---->B类型----->A类型
* 可能需要用B类型的功能,但是结果需要的是A类型,又需要转回去
*
* StringBuffer <-----> String
*/
public class StringBufferTest {
public static void main(String[] args) {
//String------->StringBuffer
//方式1:使用StringBuffer的有参构造方法
//StringBuffer(String s)
String s = "helloJavaEE" ;
StringBuffer sb = new StringBuffer(s) ;
System.out.println("sb:"+sb) ;//内容一样,但是数据类型不同
System.out.println("------------------------------") ;
//方式2:使用StringBuffer无参构造方法+append(String s)
StringBuffer sb2 = new StringBuffer() ;
sb2.append(s) ;
System.out.println("sb2:"+sb2) ;
System.out.println("------------------------------------------") ;
//StringBuffer-------->String
//有一个StringBuffer的数据
StringBuffer buffer = new StringBuffer("android") ;
//String类型构造方法:public String(StringBuffer buffer)
String str = new String(buffer) ;
System.out.println("str:"+str) ;
System.out.println("------------------------------------------") ;
//public String toString()
String str2 = buffer.toString();
System.out.println("str2:"+str2);
}
}