一、内部类
1.1 创建内部类
内部类就是在一个类中再定义一个类,内部类分为成员内部类、匿名内部类和静态内部类
内部类可以被public、default、protected和private修饰,而外部类只能够使用public和default
修饰。
内部类是编译期间的概念,在编译之后这个源文件(.java文件)会生成两个字节码文件(.class文件),所以内部类的成员变量、方法名可以与外部类相同
如果想通过外部类访问内部类,则需要通过外部类对象创建内部类对 象。创建内部类对象的具体语法格式如下:
外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
1.2 成员内部类
成员内部类是最普通的内部类,在成员内部类中可以访问外部类的所有成员
1、成员内部类定义在外部类的内部,相当于外部类的一个成员变量,成员内部类可以采用任意的
访问修饰符
2、成员内部类中的方法可以直接访问外部类的所有数据,包括私有的数据。
3、定义成员内部类后,必须使用外部对象来创建内部类对象
4、外部类不能直接使用内部类的成员和方法,先要创建内部类的对象,然后通过内部类对象来访问它的成员和方法
5、如果外部类和内部类具有相同的成员变量或方法时,内部类默认访问自己的成员变量和方法,如果要访问外部类的成员变量或方法时,可以使用this关键字(内部类默认可以引用外部类对象,引用时在对象名前 面加上“外部类名.this”)
1.3 匿名内部类
匿名内部类就是没有名字的内部类,多用于关注实现而不关注实现类的名称,在编写事件监听的代码时使用匿名内部类不但方便,而且使得代码易于维护
button2.addActionListener( new ActionListener(){
public void actionPerformed(ActionEvent e) {
System.out.println("单击了button2");
}
});
本例中,为一个按钮对象button2添加了一个事件监听器, addActionListener()方法的参数是一个匿名内部类:
new ActionListener(){ public void actionPerformed(ActionEvent e) {
System.out.println("单击了button2");
} }
匿名内部类是唯一没有构造器的类,正是没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。一般来说,匿名内 部类用于继承其他类或用于实现接口,并不需要增加额外的方法,因为 它只是对继承方法的实现或重写。
1.4 局部内部类
局部内部类是定义在方法或者一个作用域中的类,它和成员内部类的区别在于成员内部类的访问权限仅限于方法或该作用域内。注意,局部内部类就像方法中的一个局部变量一样,是不能够使用访问修饰符和static修饰符的
1.5 静态内部类
静态内部类是成员内部类加上了一个static修饰符。静态内部类不需要依赖于外部类的,并且它不能够使用外部类的非静态的成员属性或方法,在没有外部类的情况下就能够创建静态内部类的对象
总结内部类有如下几个特点:
1.静态内部类不能直接访问外部类的非静态成员,但可以通过“new 外部类().成员”的方式访问。
2.如果外部类的静态成员与内部类的成员名称相同,可通“类名.静态 名”访问外部类的静态成员;否则可通过成员名直接调用外部类的静态成员。
3.创建静态内部类中的对象时,不需要外部类的对象,可以直接创建,格式为
内部类名 对象名=new内部类名();
4.在其他类中创建内部类的对象时,不需要用外部类对象创建,格式为
外部类名.内部类名 对象名=new外部类名.内部类名();
package org.Innter;
public class hj {
String name="张三";
static int h=1;
public hj getHj(){ //在外部类中创建静态内部类
hj hj = new hj();
return hj;
}
public void say(){
System.out.println("我在说话!");
}
public static void setH(){
System.out.println("hao");
}
public static class hh {
private String name;
private int age;
public int geth(){
return h;
}
public void getname(){
String name = new hj().name;
System.out.println(name);
}
public hh(String name, int age) {
this.name = name;
this.age = age;
}
public hh() {
}
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;
}
@Override
public String toString() {
return "hh{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
}
package org.Innter;
public class test {
public static void main(String[] args) {
hj.hh hh = new hj.hh(); //在其他类中创建内部类的对象
hh.getname(); //输出张三
int h = hh.geth();
System.out.println(h); //输出1
}
}
就业解析与指导
面试官:创建了匿名类,为什么编译时提示匿名类不存在呢?
应聘者:创建匿名类时,首先要创建匿名类的接口,否则编译时提示匿 名类不存在。
面试官:成员内部类和静态内部类有什么区别?
应聘者:成员内部类的创建必须依赖于外部类,静态内部类的创建不依 赖于外部类。成员内部类可以访问外部类的所有成员,静态内部类只可 以访问外部类的静态成员变量和静态的方法。
二、抽象类与接口
2.1 抽象类和抽象方法
在面向对象的概念中,所有的对象都是通过类来描绘的;但是反过来,并不是所有的类都是用
来描绘对象的,若一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。
抽象方法指一些只有方法声明,而没有具体方法体的方法。抽象方法一般存在于抽象类或接口中。
认识抽象类
Java程序用抽象类(abstract class)来实现自然界的抽象概念。抽象类的 作用在于将许多有关的类组织在一起,提供一个公共的类,即抽象类。 而那些被它组织在一起的具体的类将作为它的子类由它派生出来。抽象类刻画了公有行为的特征,并通过继承机制传递给它的派生类。
抽象类是它的所有子类的公共属性的集合,是包含一个或多个抽象方法 的类。使用抽象类的一大优点就是可以充分利用这些公共属性来提高开 发和维护程序的效率。
定义抽象类
抽象类要使用abstract关键字声明,它可以设置属性,没有方法体的方法和有方法体的方法,抽象类没有构造器,因此它不能够被实例化,抽象类中的方法可以是抽象方法(用abstract修饰的方法,没有方法体)也可以是普通的方法
下面是抽象类的一个栗子:
package Abstact;
public abstract class Shape {
String W; //基本属性
public abstract void say(); //抽象方法
public void gh(){ //因为抽象类不能够被实例,所以非抽象方法没必要,一般是不会用的
System.out.println("kl");
}
}
总结:抽象类实际上比普通类多了一些抽象方法,其他组成部分和普通 类完全一样。
普通类对象可以直接实例化,但抽象类的对象必须经过向上转型 之后才可以得到。
虽然一个类的子类可以继承任意的一个普通类,可是从开发的实际要求 来讲,
普通类尽量不要继承另外一个普通类,而应该继承抽象类。
抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类
构造方法和类方法(用static修饰的方法)不能声明为抽象方法。
抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该 子类也是抽象类。
2.2 接口概述
接口(interface)是Java所提供的另一种重要的技术,接口是一种特殊 的类,它的结构和抽象类非常相似,可以认为是抽象类的一种变体。
接口声明
接口是比抽象类更高的抽象,它是一个完全抽象的类,即抽象方法的集 合。接口使用关键字interface来声明,语法格式如下:
[public] interface 接口名称 [extends 其他的类名]{
[public][static][final] 数据类型 成员名称=常量值;
[public][static][abstract] 返回值 抽象方法名(参数列表);
}
接口中的方法是不能在接口中实现的,只能由实现接口的类来实现。一 个类可以通过关键字implements来实现。如果实现类没有实现接口中的 所有抽象方法,那么该类必须声明为抽象类。
接口有以下特性:
1、接口中也有变量,但是接口会隐式地指定为public static final变量,并且只能是public,
用private修饰会报编译错误。
2、接口中的抽象方法具有public和abstract修饰符,也只能是这两个修 饰符,其他修饰符都会报错。
3、接口是通过类来实现的。
4、接口可以被继承,被继承的接口必须是另一个接口。
实现接口
类使用implements关键字实现接口
class 类名称 implements 接口名称[,其他接口]{ … }
在实现接口的时候,需要注意以下规定:
1、一个类可以同时实现多个接口。
2、一个类只能继承一个类,但是能实现多个接口。
3、一个接口能继承另一个接口,这和类之间的继承比较相似。
接口默认方法
Java提供了接口默认方法。即允许接口中可以有实现方法,使用default 关键字在接口修饰一个非抽象的方法,这个特征又叫扩展方法。
举个栗子:
package Abstact;
public interface Interfacetest { //接口
public void eat();
public default void say(){
System.out.println("...");
}
}
package Abstact;
public class gh implements Interfacetest { //实现类
@Override
public void eat() {
}
}
package Abstact;
public class test { //测试类
public static void main(String[] args) {
gh gh = new gh();
gh.say(); //输出...
}
}
抽象类与接口的相同点和不同点
相同点:
1、都可以被继承。
2、·都不能被直接实例化。
3、都可以包含抽象方法
4、派生类必须实现未实现的方法。
不同点:
1、接口支持多继承,抽象类不能实现多继承。
2、一个类只能继承一个抽象类,但可以实现多个接口。
3、接口中的成员变量只能是public static final类型的,抽象类中的成 员变量可以是各种类型的。
4、接口只能定义抽象方法;抽象类既可以定义抽象方法,也可以定 义实现的方法。
5、接口中不能含有静态代码块以及静态方法(用static修饰的方 法),抽象类可以
有静态代码块和静态方法。
2.3 接口的高级应用
接口可以被理解为一种特殊的类是由全局常量和公共方法所组成的,需要注意的是在接口中方法必须是public的访问权限,不可以被更改
接口的多态
java中没有多继承,一个类只能有一个父类,而继承的表现就是多态,一个父类可以有多个子类,而子类重写父类的方法,这样每个子类重写的代码不一样,自然表现形式不一样,用父类的变量去引用不同的子类,在调用这些方法的时候得到的结果和表现形式不一样,这就是多态
下面给出实例:
package Extend;
public abstract class Animal {
public abstract void eat();
public abstract void watch();
}
package Extend;
public class cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃东西");
}
@Override
public void watch() {
System.out.println("猫看电视");
}
}
package Extend;
public class mouse extends Animal{
/*public static Animal mouse() {
return new mouse();
}*/
@Override
public void eat() {
System.out.println("老鼠吃饭");
}
@Override
public void watch() {
System.out.println("老鼠看电视");
}
}
package Extend;
public class test {
public static void main(String[] args) {
Animal cat = new cat();
Animal mouse = new mouse();
cat.eat();
mouse.eat();
}
}
适配接口
在实现一个接口时,必须实现该接口的所有方法,这样有时比较浪费, 因为并不是所有的方法都是我们需要的,有时只需要使用其中的一些方 法。为了解决这个问题,引入了接口的适配器模式,借助于一个抽象类 来实现该接口所有的方法,而我们不和原始的接口打交道,只和该抽象 类取得联系。写一个类,继承该抽象类,再重写需要的方法就行。
关于具体的为啥要在接口与类中间加入抽象类
接口回调
接口回调是指可以把使用某一个接口的类创建的对象的引用赋给该接口声明的接口变量,那么该接口变量就是可以调用被类实现的方法,实际上,当接口变量调用被类实现的方法的时候,就会通知相应的对象调用接口方法,这个过程称之为对象功能的接口回调,下面我们看一个例子:
package Shapetest;
public interface shape {
public double area(); //计算面积
public double perimeter(); //计算周长
}
package Shapetest;
public class circle implements shape{
double radius;
public circle(double radius) {
this.radius = radius;
}
@Override
public double area() {
return Math.PI*radius*radius;
}
@Override
public double perimeter() {
return Math.PI*radius*2;
}
}
package Shapetest;
public class Rectangle implements shape {
double w;
double h;
public Rectangle(double w, double h) {
this.w = w;
this.h = h;
}
@Override
public double area() {
return w*h;
}
@Override
public double perimeter() {
return (w+h)*2;
}
}
package Shapetest;
public class show { //定义一个类用于显示功能
public void print(shape s){ //定义一个方法,参数为接口类型
System.out.println("面积:"+s.area());
System.out.println("周长:"+s.perimeter());
}
}
package Shapetest;
public class test { //测试类
public static void main(String[] args) {
show show = new show();
show.print(new circle(2));
//接口回调shape s替换了new circke(2)
show.print(new Rectangle(10,10));
//使用接口回调最大的好处就是可以灵活地将接口类型替换需要具体的实现类对象
}
}
2.5 java的集合
在java语言中有一个由设计优良的接口和类组成的java集合框架,以方便程序员操作成批的数据或对象
元素
接口和实现类
java语言中的集合就是一个类库的集合,包含了实现集合框架的接口。集合就像一个容器,用来存储java对象。java提供的集合API多是在java,util包中。集合框架结构图如下:
1、java集合框架的接口
Collection接口,该接口定义了存取一组对象的方法,是最基本的接口。
set接口。该接口继承Collection接口,它包含的**数据没有顺序且不可以重复**
List接口。该接口继承Collection接口,它包含的**数据有顺序且可以重复**
Map接口。该接口是一个单独的接口,不继承Collection接口,它是一种把键对象和值对象关联的容器,不可以包含重复的键
2、java集合框架的实现类
1、HashSet。实现了Set接口,为无序集合,能够快速定位一个元素。 需要注意的是,
存入HashSet中的对象必须实现HashCode()方法。
2、TreeSet。不仅实现了Set接口,还实现了Sorted接口,可对集合进 行自然排序。
3、ArrayList。实现了List接口,为有序集合,它的大小可变并且可以 像链表一样被访问。
它是以数组的方式实现的List接口,允许快速随机 存取。
4、LinkedList。实现了List接口,为有序集合,通过一个链表的形式 实现List接口,
提供最佳顺序存取,适合插入和移除元素。由这个类定 义的链表也可以像栈或队列一样被使用
5、HashMap。实现一个“键-值”映射的哈希表,通过键获取值对象,没有顺序,通过
get(key)方法来获取value的值,允许存储空对象,而且 允许键是空的。不过,键只能有一个。
Collection接口提供的主要方法:
List接口是Collection接口的子接口,List接口除了继承了Collection接口的方法以外,又提供了一些方法,如下:
就业解析与指导
三、数组与方法
3.1 数组的概念
java语言中提供数组用来提供存储固定大小的同类型数据,在java中数组也可以认为是一种数据类型,它本身是一种引用类型,java数组可以存储基本数据类型的数据,也可以存储引用数据类型,下面就是一个int类型数组的例子:
int[] x=new int[100];
下面我们看一下创建数组的时候内存分配情况图:
3.2 一维数组
一维数组就是一组具有相同类型的数据的集合,一维数组的元素是按顺序存放的。
数组的声明
在java中的数组,必须先声明数组,在为数组分配内存空间。一维数组的声明有以下两种方式,一般语法格式如下:
数组类型 数组名[];
数组类型[] 数组名;
也可以使用new关键字来创建对象:
datatype[] arrayname =new datatype[arraysize]
datatype:数组中元素的类型
arrayname:数组的名称
arraysize:是数组的大小
在java中使用{},来对数组进行初始化,如果是先设置大小的就可以用以下方法来赋值:
数组名[指定索引]=该索引位置
数组的静态初始化有两种方式:
1、类型[] 数组名=new 类型[] {元素1、元素2、元素3......}
2、类型[] 数组名={元素1、元素2、元素3......}
数组的访问
数组的访问有两种方法:
1、简单的for循环,数组中有一个length属性来获取数组的长度
for(int i=0;i<数组名.lenght;i++){
System.out.println(数组名[i]);
}
2、通过for-each来访问数组,下面是for-each的基本语法:
for(type element: array) //type是数组元素的属性 element表示数组变量(名称任意) array就是数组名
{
System.out.println(element);
}
3.4 多维数组
二维数组是一个特殊的一维数组,其中每个元素都是一个一维数组,列如:
String str[][] = new String[3][4];
多维数组的动态初始化有以下两种方式:
(1)、直接为每一维数组分配内存,格式如下:
type arrayName = new type[arraylength1][arraylength2];
int a[][]=new int[arraylength1][arraylength2]
从最高维开始,分别为每一维分配空间,例如:
String s[][] = new String[2][];
s[0] = new String[2];
s[1] = new String[3];
s[0][0] = new String("Good");
s[0][1] = new String("Luck");
s[1][0] = new String("to");
s[1][1] = new String("you");
s[1][2] = new String("!");
数组元素
二维数组也是通过索引来访问数组数组中的元素。一般格式如下:
数组名[第一维索引][第二维索引]
二维数组长度如下:
二维数组名.length
二维数组第一个索引表示行,第二个索引表示列,,这里求出来的是行的长度
二维数组的赋值
数据类型 数组名[][] = {{初值1,初值2,初值3},{初值4,初值5,初值6}}
遍历多维数组
通过双重for循环遍历出来,如下:
for(int x=0;x<num.length;x++) //num表示数组名,x表示行
{
for(int y=0;y<num[x].length;y++) //y表示列,num[x].length是求出当前行数的长度
{
System.out.println(num[x][y]);
}
}
3.5 对象数组
java API提供了一个数组类Arrays(java.util.Arrays),能够方便地操作数组,它提供的所有方法都是静态的,功能及说明如下:
public static void main(String[] args) {
int a[]=new int[2];
Arrays.fill(a,1);
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]); //输出2 2
}
Arrays.fill(a,0,1,1); //a参数是数组名,0表示起始索引,第一个1表示末尾索引,在填充时不包括末尾索引
Arrays.fill(a,1,2,2);
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]); //输出1 2
}
}
public static void main(String[] args) {
int a[]={12,11,10,9,8,7,6,5,4,3,2,1};
/* Arrays.sort(a);
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]); //输出1,2,3,4,5....、12
}*/
Arrays.sort(a,0,5);
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]); //输出8,9,10,11,12,7,6,5,4,3,2,1
}
}
public static void main(String[] args) {
int a[]={1,2,3,4,5,6,7,8,9};
int i = Arrays.binarySearch(a, 3); //参数1是数组,参数2是指定值,若指定值在数组中那么返回指定的索引
System.out.println(i); //若指定值在数组中没有那么返回-1,此处输出2
/* int i0 = Arrays.binarySearch(a, 0, 3, 3);
System.out.println(i0);*/ //输出2
//搜索键的索引,如果它包含在指定范围内的数组中; 否则, (-(insertion point) - 1)
/* int i1 = Arrays.binarySearch(a, 0, 4, 5);
System.out.println(i1); //输出5
int i2 = Arrays.binarySearch(a, 0, 4, 8);
System.out.println(i2);*/ //输出5
}
就业解析与指导
面试官:Java变量一定要初始化吗?
应聘者:不一定。Java数组变量是引用数据类型变量,它并不是数组对象本身,只要让数组变量指向有效的数组对象,即可使用该数组变量。 对数组执行初始化,并不是对数组变量进行初始化,而是对数组对象进 行初始化,也就是为该数组对象分配一块连续的内存空间,这块连续的 内存空间就是数组的长度。
面试官:数组作为方法的形参,在方法中修改形参数组的值,为什么实参数组的值也被修改了?
应聘者:在方法中数组作为参数传递的只是数组在内存中的地址(即引用),而不是将数组中的元素直接传给形参。这样的引用传递使方法的 形参和实参同时指向数组在内存中的位置,无论是通过形参还是实参修 改数组,内存中数组的值都会发生改变。
四、字符串的应用
4.1 String类的本质
String类的本质就是字符数组,String类型在java中就是文本数据类型。字符串是由字母、数字、汉字以及下划线组成的一串字符,String类的创建有两种方法:
1、直接赋值:
String 字符串名="字符串";
2、使用关键字创建:
String s=new String();
注意:使用String声明的空字符串,它的值不是null(空值),而 是"",它是实例化的字符串对象,它不包含任何字符。
public static void main(String[] args) {
String s = new String();
if (s.equals("")){
System.out.println("s=\"\""); //输出
}else {
System.out.println("s!=\"\"");
}
}
在创建String类对象,可以在构造器中传入多个值
1、可以传入一个字符串参数
public String(String original)
2、可以传入一个字符数组
public String(char[] value)
3、可以传入一个字符数组及其偏移值和取值个数
public String(char[] value, int offset, int count)
public static void main(String[] args) {
String s = new String("hello"); //传入字符串
System.out.println(s); //输出hello
char c[]={'I',' ','L','O','V','E'};
String s1 = new String(c); //传入字符数组
System.out.println(s1); //输出I LOVE
String s2 = new String(c, 2, 4); //传入字符数组带偏移和数目
System.out.println(s2); //输出 LOVE
}
4.2 String类的API的应用
JDK的API中的String类提供了许多操作方法,都在java.lang包中。
我们按照功能划分来讲解这些API
1、字符与字符串方法:
2、字节与字符串方法:
3、字符串比较方法:
4、字符串的查找方法:
5、字符串截取方式:
6、字符串拆分方法:
7、字符串替换方法:
8、其他操作:
4.4 正则表达式
正则表达式是一种可以用于模式匹配和替换的规范,一个正则表达式就 是由普
通的字符(例如字符a到z)以及特殊字符(元字符)组成的文字 模式,
它用以描述在查找文字主体时待匹配的一个或多个字符串。
下面我们看一下正则表达式的语法:
常用的正则表达式:
在String类中提供了matches()方法,用于检查字符串是否匹配给定的正 则表达式。其语法格式如下:
public boolean matches(String regex)
4.5 字符串的类型转换
java还为String类提供字符串的类型转换方法,能够将字符串转化为数组,将基本数据类型转化为字符串,以及格式化字符串
toCharArray()方法将字符串转换为字符数组:
String s="huang";
char[] chars = s.toCharArray();
for (char aChar : chars) {
System.out.print(aChar+' '); //输出h u a n g
}
基本数据类型转字符串:
public static String valueOf(boolean b) ;
public static String valueOf(char c);
public static String valueOf(int i);
public static String valueOf(long l);
public static String valueOf(float f);
public static String valueOf(double d);
public static String valueOf(Object obj);
public static String valueOf(char[] data);
public static String valueOf(char[] data, int offset, int count);
4.6 StringBuffer与StringBuilder
在java语言当中,除了String类提供了创建和处理字符串的方法外,还有StringBuffer类和StringBuilder类,后两者的使用方式类似
对String、StringBuffer和StringBuilder这3个类的选择总结如下:
·如果要操作少量的数据,建议使用String。
·在单线程操作字符串缓冲区的情况下操作大量数据,建议使用 StringBuilder。
·在多线程操作字符串缓冲区的情况下操作大量数据,建议使用 StringBuffer。
StringBuilder类的创建可变字符串的三种构造方法:
(1)、StringBuilder()构造方法。
该构造方法创建一个空的字符串缓冲区,初始容量为16个字符。
(2)、StringBuilder(int capacity)构造方法。
该构造方法创建一个空的字符串缓冲区,并指定初始容量是capacity的字符串缓冲区。
(3)、StringBuilder(String str)构造方法。
该构造方法创建一个字符串缓冲区,并将其内容初始化为指定的字符串 str。该字符串的初始容量为16加上字符串str的长度。
StringBuilder stringBuilder = new StringBuilder();
System.out.println(stringBuilder.capacity()); //输出16
StringBuilder stringBuilder1 = new StringBuilder(10);
System.out.println(stringBuilder1.capacity()); //输出10
StringBuilder eee = new StringBuilder("eee");
System.out.println(eee.capacity()); //输出19
StringBuilder类的方法
1、追加字符串:提供了许多重载的append()方法,可以接收任意类型数据,该方法能有
效的将其他数据类型转化为字符串类型,然后将字符串追加到字符串缓存区当中。其语法
格式如下
public StringBuilder append(String str)
2、插入字符串:提供了许多重载的insert()方法,可以接收任意类型的数据,将其转换
为字符串,插入到指定的字符串的缓存区位置。其语法格式如下:
//offset:要插入字符串的位置,也就是原本字符串的字符的位置
//从零开始
public StringBuilder insert(int offset, String str)
3、删除字符串:提供了两个用于删除字符串中字符的方法,第一个方法就是
deleteCharAt()方法,用于删除字符串指定位置的字符。第二个是delete()方法
用于删除指定开始位置到结束位置的子字符串,其语法格式如下:
public StringBuilder deleteCharAt(int index)
//包含start,不包含end
public StringBuilder delete(int start, int end)
4、反转字符串:提供了reverse()方法用于字符串的内容的倒序输出,其语法格式如下:
public StringBuilder reverse()
5、替换字符串:提供了两个字符替换的方法,一个是replace()方法,用于将字符串的
子字符串替换成为新的字符串,另外的一个方法就是setCharAt()方法用于将字符串的
指定字符替换成为新的字符。其语法格式如下:
//包括开始start,不包括结尾end
public StringBuilder replace(int start, int end, String str)
public void setCharAt(int index, char ch)
由于StringBuffer与StringBuilder中的方法和功能是完全等价 的,因此对StringBuffer的使用不再做介绍。
就业解析与指导
面试官:如何比较两个字符串?使用==还是equals()方法?
应聘者:简单来讲,==测试的是两个对象的引用是否相同,而equals() 比较的是两个字符串的值是否相等。除非想检查的是两个字符串是否是 同一个对象,否则应该使用equals()来比较字符串。
面试官:String是否是基本数据类型?
应聘者:不是。基本数据类型包括byte、char、short、int、long、float、 double、boolean,这8种类型都是Java中内置的类型,也叫原生类型;而 String不是,它是一个类。
五、常用类的应用
5.1 Math类
Java的Math类包含了用于执行基本数学运算的属性和方法,如初等指 数、对数、平方根和三角函数。Math类的方法都被定义为静态形式,通过Math类可以在主函数中直接调用。
Math.PI Math.sin() Math.cos() Math.toDegrees()[转换为角度数]
Math.pow(r,2)[次方 r的二次方]
5.2 Random类
Random类是一个随机数产生器,它可以在指定的取值范围内随机产生 数字。Random类提供了如下两种构造方法:
·Random():用于创建一个伪随机数产生器。
·Random(long seed):使用一个long类型的seed种子创建伪随机数产 生器。
第一种无参数的构造方法创建的Random实例对象每次以当前时间戳作为种子,因此每个对象所产生的随机数是不同的。
第二种有参的构造方法创建的Random对象同一次产生的随机数一样,也就是说,两个种子数相同的Random对 象,第一次产生的随机数字完全相同,第二次产生的随机数字也完全相 同,以此类推。
其实随机数的产生是由一个计算方法来完成的,不过该计算方法需要传入一个参数(也称为种子),无参构造传的是当前时间戳,而这个计算方法在创建好Random对象时就创建好了就已经确定好了
下面来介绍Random类中的方法:
5.3 Date类
java在java.util中提供了Date类,这个类封装了当前的日期和时间。Date类支持两种构造方法
第一种无参构造,返回的是封装当前时间的:
new Date();
第二种是有参构造,传入一个long类型毫秒数,它指的是自1970年1月1日0时0分起过去的毫秒数。格式如下:
Date(long millisec) millisecond:毫秒,千分之一秒
Date常用的方法如下:
public static void main(String[] args) {
Date date = new Date();
System.out.println(date); //输出Tue Jul 05 09:55:02 GMT+08:00 2022
long Mill=date.getTime()-100000;
Date date1 = new Date(Mill);
System.out.println(date.after(date1)); //输出true
System.out.println(date.before(date1)); //输出false
System.out.println(date.compareTo(date1)); //输出1
System.out.println(date.equals(date1)); //输出false
System.out.println(date.clone()); //输出Tue Jul 05 09:55:02 GMT+08:00 2022
System.out.println(date.hashCode());
}
5.4 Calendar类
Calendar类的功能要比Date类强大很多,而且在实现方式上也比Date类 要复杂一些。Calendar类是一个抽象类,在实际使用时实现特定的子类 的对象,创建对象的过程对程序员来说是透明的,只需要使用 getInstance方法即可:
Calendar c = Calendar.getInstance();//默认是当前日期
该类常用的方法:
5.5 Scanner类
scanner:扫描器,扫描设备
java.util.Scanner是java5的新特性,可以通过Scanner类获取用户的输入,创建Scanner对象的基本语法格式如下:
Scanner s = new Scanner(System.in)
下面三个是Scanner类的常用方法:
next在扫描遇到空格的时候就会停止扫描,而nextLine只会扫描一行(以enter为结束符)
5.6 DecimalFormat类
decimal:adj十进制的,小数的
format:n.总的安排,计划,设计,格式
v.为…编排格式,格式化
我们经常需要将数据格式化,列如取三位小数。java为我们提供了DecimalFormat类,可以将数据快速格式化
import java.text.DecimalFormat;
public class Test { public static void main(String[] args) {
double pi = 3.1415927; //圆周率 //取一位整数
System.out.println(new DecimalFormat("0").format(pi)); //3 //取一位整数和两位小数
System.out.println(new DecimalFormat("0.00").format(pi)); //3.14 //取两位整数和三位小数,整数不足部分以0填补
System.out.println(new DecimalFormat("00.000").format(pi)); //03.142 //取所有整数部分
System.out.println(new DecimalFormat("#").format(pi)); //3 //以百分比方式记数,并取两位小数
System.out.println(new DecimalFormat("#.##%").format(pi)); //314.16% long c = 299792458; //光速 //显示为科学记数法,并取5位小数
System.out.println(new DecimalFormat("#.#####E0").format(c)); //2.99792E8 //显示为两位整数的科学记数法,并取4位小数
System.out.println(new DecimalFormat("00.####E0").format(c));
//29.9792E7 //每3位以逗号进行分隔
System.out.println(new DecimalFormat(",###").format(c)); //299,792,458 //将格式嵌入文本 System.out.println(new DecimalFormat("光速为,###米每秒。").format(c)); } }
代码中的E表示为10 E8就是10的
8次方
5.7 Enum类
Enum(枚举,enumeration) 类是jdk1.5引入的新特性,存放在java.lang包中,它是一种新的类型
创建一个枚举实例:
public enum EnumTest { MON, TUE, WED, THU, FRI, SAT, SUN; }
这段代码实际上调用了7次Enum(String name, int ordinal),具体代码如 下:
new Enum<EnumTest>("MON",0);
new Enum<EnumTest>("TUE",1);
new Enum<EnumTest>("WED",2);
Enum常用方法:
comparaTo用于在一个枚举类型中的值的顺序位置
e.comparaTo(e1)
返回值为-1,表示e的位置在e1之前
返回值为1,表示e1的位置在 e的前面
其他值表示,他们在同一个位置
5.8 包装类
java是一个面向对象的语言,但java的基本数据类型却不面向对象,而在实际开发中存在许多不方便的,为了解决这种不方便,java在设计类的时候将8种数据类型设计了对应的类,这8种数据类型 和他们对应的类统称为包装类
包装类均位于java.lang包中,包装类与对应的基本类型的对应关系如下:
下面多是它们的构造方法和常用的方法
Boolean(String s)的这个方法只要传入的字符串不是“”[空字符串],其他的都是
true
Character类的构造方法:
Character c1 = new Character('c');
Character c1 = Character.valueOf('A');
以及这个类常用的静态方法:
8种基本类型的类分别为Integer、Double、Float、Short、Long、 Boolean、Byte、Character。除了Boolean和Character类,其他6种类都继 承Number类。Number类的构造函数和Number类的方法分别如下:
就业解析与指导
面试官:int和Integer有什么区别?
应聘者:Java提供两种不同的类型:原始类型(或内置类型)和引用类 型。int是Java的原始数据类型,Integer是Java为int类型提供的封装类, Java为每个原始类型提供了封装类。 引用类型和原始类型的行为完全不同,并且它们具有不同的语义。引用
类型和原始类型具有不同的特征和用法,包括:大小和速度问题,以哪 种类型的数据结构存储。另外,当引用类型和原始类型用作某个类的实 例数据时所指定的默认值不同,对象引用实例变量的默认值为null,而 原始类型的实例变量的默认值与具体的类型有关