常见工具类

  Java API(Java Application Programming Interface)是Java应用程序编程接口的缩写,Java中的API,就是JDK提供的具有各种功能的Java类,灵活使用Java API能够大大提高使用Java语言编写程序的效率,本章对Java中提供的最常用的工具类进行介绍,包括Object、包装类、字符串处理类String、StringBuffer以及StringBuilder、Math类以及日期类。
重点:

(1) Object类及其常用方法

(2) 包装类的概念及其和基本数据类型、字符串之间的相互转换

(3) 三种不同的字符串类及其用法

(4) 日期类Date、Calendar及SimpleDateFormat的使用

难点:

(1) Object类的常用方法

(2) 包装类和基本数据类型、字符串之间的相互转换

(3) 字符串类的使用

(4) 日期类的使用

1.1 Java API

Java API(Java Application Programming Interface)是Java应用程序编程接口的缩写,Java中的API,就是JDK提供的具有各种功能的Java类,由于Java类库非常庞大,而且在不断壮大,本书不可能一一介绍所有类的使用方法,读者应该养成查阅Java API文档的习惯,就像查询字典一样,在需要用到某个类的时候,可以从Java API文档中获得这个类的详细信息。Java API的帮助文档可到http://docs.oracle.com/javase/8/docs/api/下载,灵活使用Java API能够提高使用Java语言编写程序的效率,下面对Java中提供的最常用的包进行介绍。
  
java.lang:Java语言包, 该包中提供了利用Java语言进行程序设计的基础类,比如String、Math、System类,在任何类中,该包中的类不需要使用import语句进行导入,都会被自动导入。

java.util:该包中主要包含一些实用的工具类,比如集合框架类、日期处理类、字符串解析类、随机数生成类等。

java.awt:该包中主要包含处理用户界面和绘制图形图像的各种类。

java.io:该包中主要包含处理输入、输出编程的各种类。

java.net:该包中主要包含处理网络编程的各种类。

java.sql:该包中主要包含处理数据库编程的各种类。

java.lang包中常用的类如表1-1所示。

表1-1 java.lang包中的常用类
在这里插入图片描述java.util包中常用的类如表1-2所示。

表1-2 java.util包中的常用类

在这里插入图片描述表1-3 java.io包中的常用类
在这里插入图片描述java.net包中常用的类如表1-4所示。

表1-4 java.net包中的常用类
在这里插入图片描述

1.2 Object类

在Java中,有这样一个类,它是所有类的祖先类,也就是说,任何类都是其子孙类,它就是java.lang.Object。如果一个类没有显式地指明其父类,那么它的父类就是Object,也就是说,下面两条语句的作用是一样的:

public class ClassName{…} 等价于 public class ClassName extends Object{…}

如同我们称自己为炎黄子孙一样,所有的类都可以称为Object子孙类,所以,在Object类中定义的方法,在所有类中都可以使用。同时,Object类也是Java语言中唯一一个没有父类的类。

做为一个超级祖先类,Object类为子类提供了一些public修饰的方法,便于子类覆盖来实现子类自己特定的功能,下面我们要详细介绍其中的equals()方法、hashCode()方法和toString()方法。

(1)public boolean equals(Object obj)

该方法在Object类中的作用是:比较两个引用所指向的对象是否是同一个对象,即两个引用所指向对象的地址是否相等。

注意,通常情况下,Object的任何子类均可以按照自己的需要对equals()方法进行覆盖,以改变此方法的含义,所以有的类中equals()方法是比较地址,有的类中该方法不是比较地址,具体的,就看子类中该方法是如何实现的。

【例1-1定义公民类Citizen,覆盖该类的equals()方法,该方法的定义为:如果两个公民的身份id相同,则为同一个公民。
public class Citizen {
    private int id;
    private String name;
    public Citizen(int id, String name) {
        this.id = id;
        this.name = name;
    }
    //覆盖父类的equals()方法
    public boolean equals(Object o) {
        Citizen c = (Citizen) o;
        if (c.id == this.id) {
            return true;
        } else {
            return false;
        }
    }
//主方法,测试equals()方法
    public static void main(String args[]) {
        Citizen xiaoming = new Citizen(21000, "xiaoming");
        Citizen mingming = new Citizen(21000, "mingming");
        System.out.println(xiaoming.equals(mingming));
    }
}
程序运行结果:true

程序分析:上例定义了一个Citizen类,此类包含了公民的两个属性id和name,同时覆盖了equals()方法,该方法实现为:当传入对象的id和当前对象的id相等时,返回true,否则返回false。所以在main()方法最后一行调用equals()方法时,调用的实际上是Citizen类的equals()方法,xiaoming和mingming对象的id都为21000,所以程序运行结果为true。而假设如果Citizen类没有覆盖equals()方法,则在最后一行调用equals()方法时,实际调用的Object类的equals()方法,该方法比较两个对象是否指向同一块地址,所以肯定返回false,读者可自行验证。

接下来说一下"“运算符和equals()方法的区别。”"是比较运算符,既能用于比较两个基本数据类型,也能用于比较两个引用数据类型,当比较基本数据类型时,判断两个基本数据类型的字面量是否相等,当比较两个引用数据类型时,判断两个"引用"的值是否相等,也就是两个"引用"是否指向同一个对象。而equals()方法只能用于比较引用数据类型,Object类的equals()方法比较两个对象引用的值是否相等,但equals()方法通常都会被子类覆盖,所以子类中equals()方法的含义,就要看子类中的具体实现了。

【例1-2==equals()方法在String类中的区别
String str1 = "hello"; 
String str2 = new String("hello"); 
System.out.println(str1==str2); 
System.out.println(str1.equals(str2));
程序运行结果:
false
true

程序分析:因为String是引用数据类型,使用"=="运算符比较两个引用地址是否相同,第二行使用关键字new重新生成了一个String对象,所以第三行输出为false。在String类中,覆盖了Object的equals()方法,该方法判断两个String对象的内容是否相等,所以第4行输出为true。

(2) public int hashCode()

  该方法返回对象的哈希码,哈希码是一个代表对象的十六进制整数,好比对象的身份证号。在程序运行期间,每次调用同一个对象的hashCode()方法,返回的哈希码必定相同,但是多次执行同一个程序,程序的一次执行和下一次执行期间,同一个对象的哈希码不一定相同。实际上默认的哈希码是将对象的内存地址通过某种转换得到的,所以不同对象会有不同的哈希码。

  在Java中有个规定:如果equals()方法返回两个对象是相等的,那这两个对象上调用hashCode()返回的整数必须相等,否则在使用Hash类型集合时就会产生错误,所以在我们覆盖equals()方法同时,还要记得覆盖hashCode()方法。需要说明,如果equals()返回两个对象不等,它们的hashCode()也可以返回相同的整数,但是最好让它们的hashCode()返回不同的整数,这有利于提高Hash类型集合的性能。

那么重写equals()方法时,一定要重写hashcode()方法吗?

  先说说hashcode()方法调用的条件,如果你想往map里面放一个类作为map的键值,这个类又是你自己设计的,或者这个类不是你写的但是你修改了这个类的equals()方法,这个时候,你就要重写hashcode()方法,这样当你往map里放值的时候,系统会调用这个对象的hashcode()方法来生成相应的hash值,来映射相应的对象。

  如果同一个类的两个对象的属性值相等,那么他们的hashcode()一定相等吗?这个要看你具体如何实现你的hashcode()方法,如果你希望他们的值一样hashcode()也一样,你就可以这样实现。但是hashcode的实现,一般要满足几个特征,比如自反性,传递性什么的。自反性,即对任意一个非空的指引值x,x.equals(x)永远返回true,传递性,当x.equals(y)返回true并且y.equals(z)返回true时,x.equals(z)也返回true。

(3)public String toString()

  该方法返回对象的字符串表示,形如:类名@hashcode,toString()方法是一个从字面上就容易理解的方法,它的功能是得到一个能够代表该对象的一个字符串:类名+"@"+代表该对象的一个唯一的16进制数,例如下面这个例子:

【例1-3查看Object类和String类的toString()方法返回值。
public class ObjectSample {
            public static void main(String args[]){
                Object o = new Object();
                System.out.println(o);
                System.out.println(o.toString());
                String s = new String("hello");
                System.out.println(s);        
            }    
}
程序运行结果:
java.lang.Object@1db9742
java.lang.Object@1db9742
hello

程序分析:前两个输出结果表示对象o在内存中的地址,事实上返回这样的字符串没有什么实际的意义。一般子类都会覆盖该方法,让它返回有意义的文本。例如上例中的对象s的输出为"hello",这是因为字符串String类对toString()进行了覆盖,让它返回此String的本身内容。

下面通过实例来看一下如何在自己编写的类中覆盖equals()方法和toString()方法。

【例1-4】 equals()方法和toString()的覆盖
//圆类
public class MyCircle {
    private int radius;//半径
    public MyCircle(int r) {
        radius = r;
    }
    public int getRadius() {
        return radius;
    }
    public void setRadius(int r) {
        radius = r;
    }
    //覆盖Object中的equals()方法
    public boolean equals(Object obj) {
        MyCircle o = (MyCircle) obj;
        if (o.getRadius() == this.radius)
            return true;
        else
            return false;
    }
    //覆盖Object中toString方法
    public String toString() {
        return "radius = " + radius;
    }
}
//测试类
public class Test {
    public static void main(String[] args) {
        MyCircle obj1 = new MyCircle(3);
        System.out.println("obj1:" + obj1.toString());
        MyCircle obj2 = new MyCircle(3);
        System.out.println("obj2:" + obj2.toString());
        if (obj1.equals(obj2))
            System.out.println("the two objects are equal");
        else
            System.out.println("the two objects are not equal");
    }
}
程序运行结果:
obj1:radius = 3
obj2:radius = 3
the two objects are equal

程序分析:从程序的运行结果来看,我们创建的两个MyCircle对象是相等的,因为MyCircle类中覆盖的equals()方法规定,当两个MyCircle对象的半径相等时,认为这两个对象相等。而我们在调用MyCircle类的构造方法创建对象时设定这两个MyCircle对象的半径均为3,所以obj1.equals(obj2)返回true。

1.3包装类

出于对性能的考虑,Java编程语言不把基本数据类型看作对象。因为处理对象需要额外的系统开销,所以,如果将基本数据类型当作对象,就会给语言性能带来负面影响。然而,许多Java中的方法需要将对象作为参数,为了让基本数据类型的这些数据也具有面向对象的特性,Java 编程语言提供了包装类来将基本数据类型看作对象,基本类型和包装类型之间能够互相转换。
1.3.1包装类简介

包装类型和基本数据类型的名字基本相同,首字母变成了大写,但是int和char的包装类型为Integer和Character。基本数据类型不是对象层次结构的组成部分。有时需要像处理对象一样处理这些基本数据类型,可通过相应的“包装类”来将其“包装”。表1-5列出了基本数据类型及其包装类型。

表1-5基本数据类型及其包装类型
八种基本类型都有对应的包装类,图1-1是它们的继承层次结构。

基本数据类型的变量没有默认值,而包装类型的变量默认值是null。在这八个包装类中,除了Integer和Character类以外,其它六个类的类名和基本数据类型一致,只是类名的第一个字母大写即可。对于包装类说,这些类的用途主要包含两种:

a、作为和基本数据类型对应的类类型存在,方便涉及到对象的操作。

b、包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法。
1.3.2 基本类型与包装类之间的转换

包装类有什么作用呢?包装类能够完成数据类型之间(除boolean)的相互转换,尤其是基本数据类型和String类型的转换。包装类中包含了对应基本数据类型的值,封装了String和基本数据类型之间相互转换的方法,还有一些处理这些基本数据类型时非常有用的属性和方法。

由于八个包装类的使用比较类似,下面以最常用的Integer类为例子介绍包装类的实际使用。

1、实现int和Integer类之间的转换

在实际转换时,使用Integer类的构造方法和Integer类内部的intValue()方法实现int和Interger类型之间的相互转换,实现的代码如下:

int n = 10;

//将int类型转换为Integer类型

Integer in = new Integer(n);

//将Integer类型的对象转换为int类型

int m = in.intValue();

2、Integer类内部的常用方法

在Integer类内部包含了一些和int操作有关的方法,下面介绍一些比较常用的方法:

a、parseInt方法

public static int parseInt(String s)

该方法的作用是将数字字符串转换为int数值。在界面编程中,将字符串转换为对应的int数字是一种比较常见的操作。使用示例如下:

String s = “123”;

int n = Integer.parseInt(s);

则int变量n的值是123,该方法实际上实现了字符串和int之间的转换,如果字符串包含非数字字符,则程序执行将出现异常。

另外一个parseInt方法:

public static int parseInt(String s, int radix)

则实现将字符串按照参数radix指定的进制转换为int,使用示例如下:

int n = Integer.parseInt(“120”,10);

//将字符串"120"按照十进制转换为int,则结果为120

int n = Integer.parseInt(“12”,16);

//将字符串"12"按照十六进制转换为int,则结果为18

int n = Integer.parseInt(“ff”,16);

//将字符串"ff"按照十六进制转换为int,则结果为255

这样可以实现更灵活的转换。

b、toString方法

public static String toString(int i)

该方法的作用是将int类型转换为对应的String类型。

使用示例代码如下:

int m = 1000;

String s = Integer.toString(m);

则字符串s的值是"1000"。

1.3.3 字符串与基本数据类型、包装类型转换
在这里插入图片描述
1包装类转换成字符串

几乎java.lang.Object类派生的所有类提供了toString()方法,即将该类转换为字符串。例如:Characrer、Integer、Float、Double、Boolean、Short等类的toString()方法分别用于将字符型、整型、浮点型、双精度浮点型、短整型等类转换为字符串。举例如下所示:

int i1=10;

float f1=3.14f;

double d1=3.1415926;

Integer i1 = new Integer(i1);//生成Integer类

Float f1 = new Float(f1); //生成Float类

Double d1 = new Double(d1); //生成Double类

//分别调用包装类的toString() 方法转换为字符串

String si1 = i1.toString();

String sf1 = f1.toString();

String sd1 = d1.toString();

Sysytem.out.println(“si1”+si1);

Sysytem.out.println(“sf1”+sf1);

Sysytem.out.println(“sd1”+sd1);

整数转换成字符串也可以采用如下方法:

int myInt = 1234;

String myString = “” + myInt;

其它数据类型可以利用同样的方法转换成字符串

2**、字符串转换**为基本数据类型

字符串转换成整数:

String myNumber =“1234”;

int myInt = Integer.parseInt(myNumber);

字符串转换成byte、shor、int、float、double、long 等数据类型,可以分别参考Byte、Short、Integer、Float、Double、Long 类的parseXXX() 方法。

其实,JDK自从5.0版本以后,就引入了自动拆装箱的语法,也就是在进行基本数据类型和对应的包装类转换时,系统将自动进行,这将大大方便程序员的代码书写。使用示例代码如下:

//int类型会自动转换为Integer类型

int m = 12;

Integer in = m;

//Integer类型会自动转换为int类型

int n = in;

所以在实际使用时的类型转换将变得很简单,系统将自动实现对应的转换。Java允许基本类型和包装类型之间进行自动转换。例如可以自动装箱将一个基本数据类型转换为对象。

Integer intObject=new Integer(2);等价于 Integer intObject=2; //自动装箱

将基本类型转换为包装类对象的过程称为装箱,相反的过程称为拆箱。如果一个基本类型出现在需要对象的环境中,编译器会将基本类型值进行自动装箱;如果一个对象出现在需要基本类型的环境中,编辑器将对象进行自动拆箱。考虑下面的例子:

1:Integer [] intArray ={1,2,3};

2:System.out.printLn(intArray[0] +  intArray [1] + intArray[2]);

在第一行中,基本类型1、2、3被自动装箱成对象new Integer(1)、new Integer(2)、new Integer(3) ,在第二行中,对象intArray[0]、intArray[0]、intArray[0]被自动转换为int值,然后进行相加。

【例1-5】包装类、基本数据类型和字符串之间转换的综合案例。
public class TestWrapper {
    public static void main(String ars[]){
        Double obj_d = new  Double(3.14);        //基本数据类型转换为包装类
        double d = obj_d.doubleValue();            //包装类转换为基本数据类型
        Integer obj_i = new Integer("5");        //字符串转换为包装类
        String s = obj_i.toString();                //包装类转换为字符串转换
        double n = Double.parseDouble("5");        //字符串类转换为基本数据类型
        String s = obj_j.toString();                //基本数据类型转换为字符串类型
        Integer aa = 9;                         //自动装箱
        int bb = aa;                            //自动拆箱
    }
}

程序分析:通过以上案例可以看出,基本数据类型和字符串类型转换为包装类,使用包装类的构造器来完成;包装类转换为基本数据类型,调用包装类的xxxValue()方法来完成;包装类转换为字符串类型,调用包装类的toString()方法;字符串转换为基本数据类型,调用包装类的parseXXX()方法;基本数据类型转换为字符串类型,先把基本数据类型转换为包装类型,然后再调用包装类的toString()方法;装箱就是把基本类型用它们相应的包装类型包装起来,使其具有对象的性质。int包装成Integer、float包装成Float,拆箱和装箱相反,将包装类型的对象转化成基本类型类型的数据。
1.4 字符串类

字符串是我们在编程中最常使用的一种数据类型,Java中用类来描述字符串,其中最常用的字符串处理类是String,此外还有StringBuffer和StringBuilder。在本节,我们会了解每种字符串的特点,以便能在应用时选择合适的字符串类型。字符串不属于8种基本数据类型,而是一种引用类型。String对象代表一组不可改变的Unicode字符序列,对它的任何修改实际上又产生一个新的字符串,String类是final类型的类,所以String类对象的内容一旦被初始化就不能再改变。StringBuffer对象代表一组可改变的Unicode字符序列,StringBuilder是JDK5.0版本后引入的字符串处理类,其中的方法与StringBuffer类的相同。
1.4.1 String对象的创建

String是比较特殊的数据类型,它不属于基本数据类型,但是可以和使用基本数据类型一样直接赋值,也可以像引用数据类型一样,使用关键字new进行实例化。

String类型对象的实例化有两种方式:

–静态方式(常用):直接给变量赋值,如:String s1 = “abc”;  String s2 = “abc”;

–动态方式:使用new运算符动态的给变量赋值,如:String s3 = new String(“abc”); String s4 = new String(“abc”);

那么这两种方式创建的字符串是同一个字符串对象吗?答案是否定的,这两种方式创建的字符串对象是有区别的。

区别在于:使用静态方式创建的字符串,如果前后两次创建的字符串内容相同,则在方法区的常量池中只会产生一个字符串对象,即两个引用指向同一块地址。而使用动态方式创建的字符串,不管前后两次创建的字符串内容是否相同,每创建一次,都会在堆内存中会产生出不同的对象,即两个引用指向不同的地址。

对于上面采用静态方式创建的字符串s1、s2与采用动态方式创建字符串s3和s4其内存空间分配方式示意如图1-3所示。

​ 图1-3 字符串动态创建与静态创建示意图

动态创建String对象时需要用到构造方法,String类的常用的构造方法如下,更多构造方法请直接查阅Java API。

l 初始化一个新创建的String 对象,它表示一个空字符序列。

String 变量名 = new String() ;

初始化一个新创建的String对象,表示一个空字符串(" ");注意空字符串与null的区别,空字符串表示String对象的内容为空,而null表示String类的变量不指向任何的String对象。

l 初始化一个新创建的 String对象,表示一个与该参数相同的字符序列。

String 变量名 = new String (String value) ;

l String(char chars[]) 使用一个字符数组创建一个String对象。

另外String在使用的时候不需要用import语句导入。

注意,当使用"+“运算符进行运算时,如果参与运算的有字符串,则”+“的含义为进行字符串连接,当参与运算的没有字符串时,则”+"的含义为算术运算符加号。例如:


String str1 = "hello ";

String str2 = "world"; 

System.out.println (str1 + str2);  //输出结果为"hello world"

System.out.println(5 + 6 + 'A');  //输出结果为76

System.out.println(5 + 6 + "A");  //输出结果为11A

System.out.println(5 + "A" +6);  //输出结果为5A6

1.4.2 String 对象的不可变性

任何一个String对象在创建之后都不能对它的内容作出任何改变。对于连接、获得子串和改变大小写等操作,如果返回值同原字符串不同,实际上是产生了一个新的String对象,在程序的任何地方,相同的字符串字面常量都是同一个对象,下面的代码会改变字符串s的内容吗?

String s = “Java”;

s = “HTML”;

答案是不会。第一条语句创建了一个内容为"Java"的String对象,并将其引用赋值给s。第二条语句创建了一个内容为"HTML"的新String对象,并将其引用赋值给s。赋值后第一个String对象仍然存在,但是不能再访问它,因为变量s现在指向了新的对象HTML,如图1-4所示。

图1-4字符串是不可改变的,一旦创建,它们的内容不能修改

因为字符串在程序设计中是不可改变的,但同时又会被频繁地使用,所以Java虚拟机为了提高效率并节省内存,对具有相同字符串序列的字符串直接使用同一个实例。例如下面的语句:

String str1 = "hello"; 

String str2 = new String("hello");

String str3 = "hello";

System.out.println(str1==str2); 

System.out.println(str1==str3);

程序运行结果:

false

true
1.4.3 字符串的比较

String类提供了多种对字符串比较的方法,具体如表1-6所示。

表1-6 字符串比较方法
在这里插入图片描述

例如,下面的语句先显示true,然后显示false.
String s1 = new String("welcome to Java");
String s2 = "welcome to Java";
String s3 = "welcome to C++";
System.out.println(s1.equals(s2)); //true
System.out.println(s1.equals(s3));//false
【例1-5】字符串equals方法练习
String s1 = "abc";
String s2 = new String("abc");
String s3 = new String("abc");
String s4 = "abc";
System.out.println(s1.equals(s2));   //true
System.out.println(s1.equals(s4));   // true
System.out.println(s2.equals(s3));   //true
程序分析:equals方法用来比较两个字符串是否相等。
【例1-6】重写equals()方法,判断不同的点,是否是坐标系上的同一点。
//点类
public class Point {
    private int x; //x坐标
    private int y;//y坐标
    public Point(int x,int y){
        this.x = x;
        this.y = y;
    }
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
    @Override
    public String toString() {
        return "("+x+","+y+")";
    }    
        //如果x,y的值相同,就认为是坐标上的同一点
    public boolean equals(Object obj) {
          if(obj == null){
              return false;
          }
          if(this == obj){
              return true;
          }
          if(!(obj instanceof Point)){
              return false;
          } else {
              Point p = (Point)obj;
              if(p.x==x&&p.y==y){
                  return true;
              } else {
                  return false;
              }
          }
        }
}
//测试类
public class TestPoint {
        public static void main(String[] args) {
            Point p1 = new Point(55,66);
            Point p2 = new Point(55,66);
            Point p3 = new Point(22,33);
            System.out.println(p1.equals(p2));
            System.out.println(p1==p2);
            System.out.println(p1.equals(p3));
            System.out.println(p1==p3);
        }
}
程序运行结果:
true
false
false
false

程序分析:上例测试中main()方法中实例化了3个点,分别使用equals方法与进行比较,因为Point类覆盖了父类的equals()方法,该方法判断如果两个Point对象的x坐标和y坐标相等,则返回true,所以第1行输出为true,""运算符比较引用数据类型时,判断两个引用是否指向同一个对象,p1,p2,p3都分别是不同的对象,所以第2行和第4行输出为false。

compareTo方法也可以用来对字符串进行比较。方法如下:

s1.compareTo(s2)

如果s1与s2相等,那么该方法返回值为0;如果按字典序(即以统一码的顺序)s1小于s2,那么方法返回值小于0;如果按字典序s1大于s2,方法返回值大于0。

方法compareTo返回的实际值是依据s1和s2从左到右数第一个不同字符之间的距离得出的,例如,假设s1为“abc”,s2为“abg”,那么s1.compareTo(s2)返回-4。首先比较的是s1与s2中第一个位置的字符(a与a)。因为它们相等,所以比较第二个位置的两个字符(b与b)。因为它们也相等,所以比较第三个位置的两个字符(c与g)。由于字符c比字符g小4,所以比较之后返回-4。如果使用像>、>=、<或<=这样的比较运算符比较两个字符串,就会发生错误,替代的方法就是使用s1.compareTo(s2)来进行比较。

如果两个字符串相等,equals方法返回true;如果不相等,方法返回false。compareTo方法会根据一个字符串是否等于、大于或小于另一个字符串,分别返回0、正整数或负整数。

1.4.4字符串与数组之间的转换

字符串不是数组,但是字符串可以转换成数组,反之亦然。

(1)与字符数组之间的转换

为了将字符串转换成一个字符数组,可以使用toCharArray方法。例如,下述语句将字符串"Java "转换成一个字符数组:

Char[] chars= “Java”.toCharArray();

因此chars[0]是’J’,chars[1]是’a’,chars[2]是’v’,chars[3]是’a’。

还可以使用方法getChars(int srcBegin,int srcEnd,char[]dst,int dstBegin)将下标从srcBegin到srcEnd-1的子串复制到字符数组dst中下标从dstBegin开始的位置。例如,下面的代码功能是把字符串"CS3720"中下标从2到6-1的子串"3720"复制到字符数组dst中,赋值时下标从4开始的位置:

Char[] dst={‘j’,‘a’,‘v’,‘a’,‘1’,‘3’,‘0’,‘1’};

“CS3720”.getChars(2,6,dst,4);

这样,dst就变成了{‘j’,‘a’,‘v’,‘a’,‘3’,‘7’,‘2’,‘0’}。

为了将一个字符数组转换成字符串,应该使用构造方法String(char[])或者方法valueOf(char[])。例如,下面的语句使用String构造方法把一个字符数组构造成一个字符串:

String str = new String(new char[]{‘j’,‘a’,‘v’,‘a’});

下面的语句使用valueOf方法把一个字符数组构造成一个字符串:

String str = String.valueOf(new char[]{‘j’,‘a’,‘v’,‘a’});

(2)与字节数组之间的转换

Java中能够把字符串转换为字节数组,有3种形式。

形式1:public byte[] getBytes()

方法定义:以默认编码把字符串转换为字节数组

形式2:public byte[] getBytes(Charset charset)

方法定义:按照指定的字符集把字符串转换为字节数组

形式3:public byte[] getBytes(String charsetName)

方法定义:按照指定的字符集把字符串转换为字节数组

【例1-7】 使用平台的默认字符集,统计一个字符串所占用的字节数。
public class TestStringByte{ 
    public static void main(String[] args) {
        String str = "Java语言程序设计";
        byte bytes[] = str.getBytes();
        System.out.println(bytes.length);
    } 
}
程序运行结果:
16

程序分析:通过getBytes()方法把字符串转换成字节数组,字节数组的长度就是字符串所占的字节数。

【例1-8】通过字节数组创建字符串对象
public class TestStringCharset { 
    public static void main(String[] args) {
        byte[] bName = new byte[10]; 
        String name1 = "张三"; 
        try{ 
            bName = name1.getBytes("utf-8"); //这种编码方式一个中文占三个字节
          String name2 = new String(bName,"utf-8"); 
          System.out.println("name2="+name2); 
        for(int i = 0;i< bName.length;i++){ 
              System.out.print(bname[i]); 
            } 
        }catch (UnsupportedEncodingException e){ 
            e.printStackTrace(); 
        } 
    } 
}
程序运行结果:
name2=张三
-27-68-96-28-72-119

程序分析:getBytes()是将一个字符串转化为一个字节数组。String的getBytes()方法是得到一个系统默认的编码格式的字节数组。将一个String类型的字符串中包含的字符转换成byte类型并且存入一个byte数组中。在Java中的所有数据底层都是字节,字节数据可以存入到byte数组。存储字符数据时(字符串就是字符数据),会先进行查表,然后将查询的结果写入设备,读取时也是先查表,把查到的内容打印到显示设备上,getBytes()是使用默认的字符集进行转换,getBytes(“utf-8”)是使用UTF-8编码表进行转换。例如: byte [] b_Uf8 = “中国”.getBytes(“UTF-8”);//获得字节数组 String s_Utf8 = new String(b_utf8,“UTF-8”);//使用指定的UTF-8编码来将byte[]解析成字符串。

(3)String类与数组的转换示意图

字符串可以和字节数组与字符数组之间互相转换,

其转换过程如图1-5所示

1.4.5 String中的常用的方法

String的一些常用方法如表1-7所示。

表1-7 String类的常用方法
在这里插入图片描述
在这里插入图片描述
下面对常用的一些方法进行详细说明,为了便于说明,方法中使用的示例字符串为:str=“this is a test!”;

(1)求长度

方法定义:public int length() 。

方法描述:获取字符串中的字符的个数。

例如:

str.length()

结果:

15

(2)获取字符串中的字符

方法定义:public char charAt(int index)。

方法描述:获取字符串中的第index个字符,从0开始。

例如:

str.charAt(3)

结果:

s

注意:是第4个字符。

【例1-9】 统计一个字符串中字符e出现的次数。
public class TestString {
    public static void main(String[] args) {
        String s = "abecedkjkacedjkdseddklj";
        int num = 0;
        for(int i=0; i<s.length(); i++){
            char c = s.charAt(i);
            if(c == 'e'){
                num++;
            }
        }
        System.out.println("该字符串中字符e出现"+num+"次");
      }
}

Date类中常用方法

在这里插入图片描述ate类不支持国际化。现在我们更应该多使用Calendar类来实现日期和时间字段之间转换,使用DateFormat类来格式化和分析日期字符串,Date中的相应方法已废弃。

【例1-17】Date类常用方法练习
public class TestDate {
    public static void main(String[] args) {
        Date now = new Date();//获取当前系统时间
        System.out.println(now); //获取1970年1月1日1000毫秒之后的时间
        Date d1 = new Date(1000);
        System.out.println(now.after(d1));
        System.out.println(now.before(d1));
        System.out.println(now.compareTo(d1));
    }
}
程序运行结果:
true
false
1
程序分析:本程序主要练习日期类的几个常用方法,这几个方法的详细说明请参见表1-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值