Java学习指南(14) 常见工具类

本文是《Java学习指南》原书的网络版,作者邵发,拥有本书的全部权利。相关视频课程在此查看

目录

第14章 常见工具类

14.1 字符串

14.2 包装类

14.3 控制台界面

14.4 随机数

14.5 字符


14章 常见工具类

14.1 字符串

String类和Math类一样,也是Java自带的基础类,前面的练习中已经反复使用过。本节课介绍String类的几个常见用法。

14.1.1 字符串的拼接

使用加号可以直接拼接字符串。例如,

String s = "阿发" + "你好";

当拼接一个对象时,会自动调用该对象的toString()方法,例如,

Student w = new Student( 201801, "wang", true);

String result = "结果:"  + w;

相当于

String result = "结果:"  + w.toString();

14.1.2 字符串的长度

在Java语言里,无论是中文字符还是英文字符,都只算作一个字符。使用length()方法可以取得字符串对象的长度,例如,

String s = "阿发nihao";

int n = s.length();

这时,由于不区分中英文,所以这个字符串的长度为7。

14.1.3 空字符串

空字符串,是指长度为0的字符串。例如,

String s = "";

int n = s.length();

这里的s是一个正常的字符串对象,其中有0个字符。

注意,空字符串和null是两回事。null表示空对象,即不指向任何对象。

14.1.4 获取子串

使用substring() 方法可以获取一个字符串的子串,需要传入起止位置作为参数。例如,

String s = "阿发nihao";
String a1 = s.substring(1); // 从s[1]开始到最后
String a2 = s.substring(1, 4); // s[1],s[2],s[3]

需要注意的是,a2的值为"发ni",不包含s[4]的值。

14.1.5 判断内容是否相同

使用equals()方法可以判断两个字符串的内容是否相同。例发,

String s1 = new String("nihao");
String s2 = new String("nihao");
if(s1.equals(s2))
{
    System.out.println("相同");
}

可能有人会问,为什么不直接使用:

if(s1 == s2 ) // 错误的写法!
{
    System.out.println("相同");
}

这是一个初学者常见的错误写法。在Java里,== 用于判断s1和s2是否“同一个对象”,而equals方法用于判断s1和s2是否“内容相同”。

打个比方:小王和小李都是18岁,则可以说 wang.equals( li )。但是显然,小王和小李不是同一个对象( wang != li )。

14.1.6 字典序比较

字典序比较,即比较两个字符串的先后顺序。例如,如果要把一个班上所有同学的姓名排序,就用得上compareTo( ) 方法。

String s1 = "liming";
String s2 = "lilei";
if( s1.compareTo( s2 ) < 0)
    System.out.println(s1 + "位于前面");
else
    System.out.println(s2 + "位于前面");

在这里,由于if语句后只跟一条语句,所以可以把大括号省略不写。但对于初学者,还是要坚持使用大括号的。

对于s1.compareTo ( s2 ) ,如果返回值小于0,说明s1在前面。如果大于0,说明s1大。如果等于0,说明s1和s2内容相等。

需要注意的是,"Liming" 和 "liming" 不是相同的字符串,按字典顺序,Liming应排在liming的前面。(大写的在前面)。如果想不区分大小写进行比较,可以用compareToIgnoreCase() 方法。

14.1.7 格式化

使用format() 可以得到一个格式化的字符串。format是一个String类的静态方法,示例用法如下,

String s = String.format( "姓名:%s, 年龄: %d , 身高:%.2f", "邵发", 35, 1.75 );

则返回的结果s的值为 "姓名:邵发, 年龄: 35 , 身高:1.75" 。

其中,第一个参数是格式字符串,表示结果的格式。里面的%s, %d, %.2f为格式符,将替换为后面参数的值。

%s : 替换为一个字符串 (s , string)

%d : 替换为一个整数 (d, decimal)

%.2f : 替换为一个小数,并保留2位小数点。 (f ,float point)

 

14.1.8 查找子串

使用indefOf( ) 方法可以在一个大字符串里查找一个子串。例如,

String s = "China is a great country";
int pos = s.indexOf("great");
if(pos <0)
{
    System.out.println("没找到");
}

其中,indexOf() 方法将返回"great"出现的位置。如果找到了,则返回首字符g的位置;如果没找到,则返回-1。

indexOf()还有另一个重载的方法,带一个参数fromIndex,表示从什么位置开始查找。

例如,

 int pos = s.indexOf("great", 10); //从s[10]开始找

14.1.9 前缀后缀

还有两个方法:startsWith() 用于判断前缀,endsWith() 用于判断后缀。示例用法如下,

String filename = "test.mp4";
if( filename.endsWith(".mp4") )
{
    System.out.println("支持此视频格式!");
}

其中,endWith() 方法用于判断filename是否以".mp4" 结尾。

14.1.10 截除空白

使用trim() 方法,可以去除字符串左右两边的空白字符。例如,

String s = "  你好 yes OK  ";

String s2 = s.trim();

其中,字符串s的左右的空白字符都会被清掉,并返回清理后的字符串的值: "你好 yes OK" 。

需要提醒的是,字符串里面的字符不会被清掉,仅清楚两边的空白字符。

14.1.11 分割

使用split() 方法可以将一个大字符串分割为多个小字符串,返回一个字符串数组。例如,将一个字符串按逗号分割,示例如下,

String s ="小张, 小王, 小李";
String[] names = s.split(",");
for(int i=0; i<names.length; i++)
{
    String name = names[i].trim();
    System.out.println(name);
}

 

14.2 包装类

在第11章中提到,Java是完全面向对象的语言,所有的类的顶级父类都是Object类。然而,有一些类型却似乎游离于这个规则之外,那就是基本数据类型byte, short, int , long, double, float, boolean。

其中的有些类型,如int, double, boolean类型,我们已经演练掌握。可以发现,这些类型并不是class,因而在将来的某些场景下,会存在一些尴尬(以后会说)。

为了将所有的类型统一到“类”的范畴,可以将基本类型包装一下。比如,设计一个MyInteger类来表示整数,

public class MyInteger
{
    public int value;

    public int getValue()
    {
        return this.value;
    }

    public void setValue(int value)
    {
        this.value = value;
    }
}

这样便得到一个类,这个类看起来和int差不多,但它已经被统一到了Object的子类,以后便可以按类和对象的设计思路来使用。

14.2.1 包装类

在Java里,每一种基本类型都对应一个包装类型 ( Wrapper Class) 。所列如下,

long    <=>   Long

int     <=>   Integer

short   <=>   Short

byte    <=>   Byte

double  <=>   Double

float   <=>   Float

boolean <=>  Boolean

可以看到,int对应的包装类型是Integer,它是Java自带的基础类。下面就以Integer类为例,介绍包装类的一般性用法。

14.2.2 装箱拆箱

下面我们看一下,int类型与Integer类型如何相互转换。

Integer a = new Integer(10); // int => Integer
int b = a.intValue();// Ingteger => int

可以看到,int与Integer的转换非常的简单。其中,把int转成Integer,称为“装箱”过程;反之 ,把Integer转成int时称为“拆箱”。这两个术语其实没有什么高深的地方,就是相互转换而已。

进一步的,上述的转换过程可以写得更简洁一些,

Integer  k = 123;
int  m = k;

现在的Java版本都是支持这么写的,这样的自动转换的过程称为“自动装箱拆箱”。

也就是说,int与Integer之间的转换没什么需要注意的,几乎可以随心所欲。

14.2.3 Integer与String转换

下面演示一下Integer与String之间的转换。示例如下,

String s = String.valueOf( 123 ); // int => String
int  a = Integer.valueOf("123"); // String => int

其中,Integer.valueOf() 是一个静态方法,用于将String转成Integer。

实际上,包装类Integer里还提供了多种有用的方法,以方便我们来进行整数相关的操作。

14.2.4 值的比较

对于包装类型的对象,要比较其值大小,应该用equals方法,不能用==或!= 来比较。例如,以下代码是一个初学者容易犯的错误,

Integer a = new Integer(123);
Integer b = new Integer(123);
if( a == b) // 错误!!
    System.out.println("相等");
else
    System.out.println("不相等");

应该改为:

if( a.equals(b) ) // 正确
    System.out.println("相等");
else
    System.out.println("不相等");

原因在14.1节里介绍字符串的值比较时,已经说过。

在Java里,== 用于判断s1和s2是否“同一个对象”,而equals方法用于判断s1和s2是否“内容相同”。

打个比方:小王和小李都是18岁,则可以说 wang.equals( li )。但是显然,小王和小李不是同一个对象( wang != li )。

14.2.5 包装类的作用

为什么要设计这些包装类呢?主要原因有二:

其一,包装类里包含了大量工具方法。刚才所用的Integer.valueOf()就是一个常用的方法。

其二,在设计上,将所有类型统一成 “类”的范围,都是Object的子类,以方便程序的设计处理。

14.3 控制台界面

控制台 (Console),是在上个世纪,在图形界面出现之前的、一种基于文字的用户交互界面。如今的操作系统下一般都还保留有这种古老的操作界面,比如在Windows下就可以找到DOS命令行窗口程序。如下图所示,

这种黑乎乎的窗口,就称为控制台窗口。在个窗口里,只能以输入命令行的方式与程序交互。

现今,这种基于控制台的输入输出方式早已经绝迹,那么,为什么在这一节里还要介绍这种技术呢?

第一,这种控制台技术在将来的正式开发中(公司里)不会用到;

第二,介绍控制台技术,目的仅在于辅助语法练习,模拟用户交互。

14.3.1 控制台类 AfConsole

为了便于大家的练习,提供一个控制台类AfConsole,使用它就可以很方便的实现基于控制台的程序。AfConsole的源码在课程网盘里可以找到,直接拷贝加到项目里即可。

下面用一个例子来展示AfConsole的使用:

1

2

3

4

5

6

7

8

9

10

11

12

13

AfConsole c = new AfConsole();

c.print("请输入用户名: ");

String username = c.readString("guest");

c.print("请输入密码: ");

String password = c.readString("");

if(password.equals("123456"))

{

c.println(username + ",你好! ");

}

else

{

c.println("密码错误!");

}

第1行,创建一个AfConsole对象;

第3行,c.readString() 用于从控制台获取用户输入的用户名;

第5行,c.readString() 获取用户输入的密码;

第6行,判断用户输入的密码是否正确,如果正确,则提示成功登录;否则,提示密码输入错误。

具体操作演示请参考视频教程。

有的同学会提示疑问:在其他教程看到的Scanner类,为什么在这里不用呢?原因在于,Scanner这个类用处不大,属于过时的设计,在以后的工作中绝无可能用到。(实际是Java里很少已经过时的东西)。

14.4 随机数

随机数在工程应用里有时会用到,比如,在设计牌类游戏时,洗牌操作就涉及随机数技术,每次开始游戏之前要把54张牌的顺序随机打乱。又比如,在抽奖、摇号、抽签等功能也需要使用随机数。

在涉及随机数时,需要使用Java 的一个基础类: java.util.Random。例如,

Random rand = new Random();
int s = rand.nextInt(1001);

其中,nextInt(1001) 表示生成一个0~1000之间的随机数。下面通过几个例子,来了解java.util.Random这个类的简单的使用方法。

注意: rand.nextInt ( N ) 生成的随机数范围是[0.. N-1],是不包括N的。

14.4.1 示例1

先看一个简单的应用。要求生成3个0~1000的随机数。

示例代码如下,

package my;
import java.util.Random;

public class HelloWorld
{
    public static void main(String[] args)
    {
        Random rand = new Random();
        for(int i=0; i< 3; i++)
        {
            int s = rand.nextInt(1001);
            System.out.println("生成随机数: " + s);
        }
    }
}

注意,在使用Random类时,要记得 import java.util.Random导入一下。

运行这段代码,可以发现每次会生成3个位于0-1000之间的随机数。

14.4.2 示例2

公司有96人,在年会活动上抽奖。要求写一个程序,抽出一个特等奖。(特等奖仅1人)

示例代码如下,

Random rand = new Random();
int s = rand.nextInt(96);
System.out.println("恭喜:" + (s+1) + "号员工!");

其中, rand.nextInt( 96 ) 将返回介于0-95 之间的随机数。

14.4.3 示例3

公司有96人,在年会活动上抽奖。要求写一个程序,抽出3个一等奖。

示例代码如下,

int[] result = new int[3];
int count = 0;
Random rand = new Random();

while( count < 3)
{
    // 抽一个幸运员工, s是它的号码    
    int s = rand.nextInt(96);
    // 检查s是否已经中过奖了
    boolean exist  = false;

    for(int i=0; i<count; i++)
    {
        if(result[i] == s)
        {
            exist = true;
            break;
        }
    }

    //
    if(exist)
    {
        continue;
    }
    else
    {
        result[count] = s;
        count ++;    
    }
}
for(int i=0; i<result.length; i++)
{
    System.out.println("第" + (result[i] + 1) + "号获奖!");
}

具体的代码逻辑请参考视频教程的讲解。

14.5 字符

字符 (Character) ,代表一个文字或符号。在 Java 语言里,用char类型表示字符。例如,

char c1 = 'A'; // 英文字母
char c2 = '9'; // 数字
char c3 = ' '; // 英文标点 (空格)
char c4 = '邵'; // 中文
char c5 = '。'; // 中文标点(句号)
char c6 = 'の'; // 日文
char c7 = '며' ; // 韩文
char c8 = 'β'; // 希腊字母c1 = 'A';

也就是说,无论是中文、日文、韩文、希腊文... ,几乎地球上人类的所使用的所有文字和符号,都可以用char表示。

14.5.1 字符的写法

在书写字符常量时,须用单引号括起来。例如,

char c4 = '邵';

 

看起来很简单,但是初学者可能会犯以下错误,

(1)只能表示一个字符

char  a = 'Ab' ;  // 错误! 单引号内只能有一个字符 !

(2)要用英文单引号括起来

char  a= ‘A’;  // 错误! 不能用中文单引号 !

(3)不要乱加空格,因为空格也是一个字符

char  a= ' A  ';    // 错误! 单引号内不能多加空格!

(4)必须用单引号,而不是双引号

char a = "邵";    // 错误! 双引号表示的是字符串!

14.5.2 字符编码

实际上,每个字符都对应一个数字,称为字符编码。

例如,

char c = 'A';
int n = c;
System.out.println("编码为: " + n);

 

来了解一下常见的字符的编码:

'A'为65  , 'B'为66 ...  

'a'为97,  'b'为98...

'0' 为48, '1' 为49 ...

空格字符' '是32  ..

必须强调的是,并不要求大家记住每个字符的编码是多少。因为字符的数量很大,是不可能记住的。我们只需要明白,每个字符都对应一个数字即可。

地球上所有的语言和文字符号大概有十几万之多,把这些符号统一编号,称为Unicode编码。例如,字符 '邵' 的编码是37045。可以用下面的代码来验证一下,

char c = '邵';
int n = c;
System.out.println("编码为: " + n);

这段代码,就可以打印输出字符'邵' 对应的Unicode编码是多少。

在所有的Unicode编码序列中,把前面128个字符的编码,称为ASCII编码。就也是说,ASCII码是Unicode的子集,是很小的一部分。其中包括了小写字母、大小写母、数字(0-9)、英文标点符号、控制字符等。

14.5.3 字符算术

由于字符对应一个整型数字,所以字符也可以进行简单的加减算术运算的。例如,

char result = 'A' + 2;

由于'A', 'B', 'C', ..., 'Z' 序列的编码是递增的,因此可以推算出result的值应该是 'C'。

再例如,

int n = 'C' - 'A';  // 值为2

int k = '2' - '0';   //值为2

需要区分的是,'2' - '0' 其实就是50 - 48 ,是它们对应的数字相减。

14.5.4 字符与字符串

字符串,其实就是一串字符。所以char和String之间是可以相互转换的。

v String => char的转换

String str = "afanihao阿发你好";
char ch = str.charAt(8); // 下标从0开始计数
char[] chs = str.toCharArray();

v char => String的转换

char[] chs = {'阿', '发', '你', '好'};
String str = new String(chs, 1,3);
str += '的';

再例如,在字符串字符中查找字符,可以用String的indexOf() 方法。示例代码如下,

String str = "afanihao阿发你好";
int p = str.indexOf('发');
System.out.println("位置: " + p);

字符操作在工程应用中不是重点,这些用法大家只需要稍作了解即可。

小结一下,关于字符类型,我们只需掌握两点:

(1) 学会用单引号表示一个字符

(2) 了解每个字符都对应一个数字 (但不需要记住具体的值)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿发你好

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值