《疯狂Java讲义》读书笔记(四):Java基础类库

2023-11-10

第七章 Java基础类库

①使用Scanner获取键盘输入:Scanner类提供了多个构造器,不同构造器可以接收文件、输入流、字符串作为数据源,主要提供了2个方法:hasNextXXX()是否还有下一个输入项,XXX可以表示IntLong等,如果只是判断是否包含下一个字符串,直接使用hasNext().

还有nextXXX()方法,与上一个方法相同。用法:Scanner sc=new Scanner(System.in); while(sc.hasNext()){......}

Scanner还可以读取文件输入,只要在创建Scanner对象时传入一个File对象作为参数,例如:Scanner sc=new Scanner(new File("myFile.txt"));while(sc.hasNextLine()){...}

Java提供了DataCalendar来处理日期、时间,其中Data是一个已经过时的API,推荐使用Calendar

System类:有2个获取系统当前时间的方法currentTimeMillis()nanoTime(),后者是纳秒为单位,很少用。System类还提供了一个System.identityHashCode(str)来返回指定对象的精确hashCode值,也就是根据该对象的地址计算得到的hashCode值。当某个类的hashCode()方法被重写后,该类实例的hashCode方法就不能唯一地标识该对象,但通过identityHashCode()方法返回的hashCode值,依然是根据该对象的地址计算得到的hashCode值。例如:

String s1=new String("HelloWord");

String s2=new String("HelloWord");

 System.out.println("s1的哈希值:"+s1.hashCode()+" s2的:"+s2.hashCode()); 

//输出:s1的哈希值:-1094206756 s2的:-1094206756  相同。

System.out.println("s1的identty:"+System.identityHashCode(s1)+" s2的:"+System.identityHashCode(s2));

//输出: s1的identty:846725353 s2的:1686362849 是不相同的。

String s3="java";String s4="java";

System.out.println("s3的identty:"+System.identityHashCode(s3)+" s4的:"+System.identityHashCode(s4));

//输出:s3的identty:211230037 s4的:211230037  相同的

Runtime类代表Java程序运行时环境,每个Java程序都有一个对应的Runtime实例,应用程序不能创建自己的Runtime实例,但是可以通过getRuntime()方法获取与之相关的Runtime对象。

Runtime rt=Runtime.getRuntime();

System.out.println("处理器数量:"+rt.availableProcessors());

System.out.println("空闲内存数:"+rt.freeMemory());

System.out.println("可用最大内存数:"+rt.maxMemory());

rt.exec("notepad.exe");//启动记事本程序

rt.exec("write.exe");//启动写字板

rt.exec("calc.exe");//计算器

③常用类:Object类是所有类、数组、枚举类的父类,Java允许把任何类型的对象赋给Object类型的变量。当定义一个类没有使用extends关键字为它显式指定父类,则该类默认继承Object父类。Java为工具类的命名习惯是添加一个字母s,比如操作数组的工具类是Arrays操作集合的工具类是Collections

StringStringBufferStringBuilderString类是不可变类,一旦String的对象创建以后,包含在这个对象中的字符序列是不可改变的,直到对象被销毁;StringBuffer对象则代表一个字符序列可变的字符串,当一个StringBuffer被创建后,通过StringBuffer提供的append()insert()reverse()setCharAt()setLength()方法可以改变这个字符串对象的字符序列,一旦通过StringBuffer生成了一个最终想要的字符串,就可以调用它的toString()方法将其转换为一个String对象。StringBufferStringBuilder基本相同,StringBuffer是线程安全的,StringBuilder没有线程安全功能,所以性能略高,一般情况下,应优先考虑使用StringBuilder创建字符串对象。(builder读法相当于建筑,不安全的 ^_^buffer 不服,就是安全的。^_^

String常用的方法:

StringStringBuffer buffer)和StringStringBuilder builder)根据括号里面的对象来创建对应的String对象;②char charAt(int index);获取指定位置的字符。长度从0-length()-1

int compareTo(String anotherStr)比较两个字符串的大小,如果相等,则返回0,不相等时有两种情况,第一种是两个字符串从第0个字符串开始比较,返回第一个不相等字符差。另一种情况是较长的字符串的前面部分恰巧是较短的字符串,则返回它们的长度差。

String concat(String str)将该String对象与str连接在一起,相当于“+”的功能。

boolean endsWith(String str)返回该String对象是否以str结尾。

boolean equals(Object obj)判断字符串与制定对象是否相等。

boolean equalsIgnoreCase(String str)也是判断是否相等,只是忽略大小写。

byte[] getBytes()String对象转换成byte数组。

int lastIndexOf(int ch,int fromIndex)可以只有第一个参数,也可以是String类型的参数,fromIndex是字符串从那个位置开始最后一次出现的位置。

10int indexOf();用法类似,是第一次出现的位置。

11String replace(char oldChar,char newChar);将后面的字符替换前面的字符,凡是出现该字符都会被替换掉。

12String substring(int beginIndex);substring(int beginIndex,int endIndex);截取字符串,第一个是截取到后面,第二个是从beginend位置。注意与C#的对比,C#语言的substring(int beginIndex,int endIndex);是从begin开始,截取后面数字代表的长度。

13char[] toCharArray();String对象转换成char数组,toLowerCase()toUpperCase()将字符串转为大小写。

Math类:Math类的构造器都定义成private,因此无法创建它的对象,所有的方法都是类方法,可以通过类名直接调用Math类还提供了两个类变量:PIE,值分别是π和e。常用方法:

①四舍五入取整:round(number);

②计算平方根:sqrt(num);

③计算立方根:cbrt(num)

④乘方:pow(num1num2);即num1num2次方。

max()min():返回两个数的最大、最小值。

random()返回一个伪随机数。0~1之间。

Random类的对象中,可以生成一个某个范围内的随机数:rand.nextInt(30);0~30之间的随机整数,不包含30说明,使用Random类直接生成的对象,生成的随机数并不是真正随机,而是伪随机,即对象会产生相同的数字序列,为了解决这个问题,可以使用当前时间作为Random的种子,如:Random rand=new Random(System.currentTimeMillis()); 在多线程环境中,可以使用:ThreadLocalRandom rand=ThreadLocalRandom.current();  int var1=rand.nextInt(5,20);生成5~20之间整数。

BigDecimal:先看一个程序:

double b=(double)0.05+(double)0.01;

System.out.println(b); //输出:0.06000000005

System.out.println("0.05+0.01="+(0.05+0.01));//输出:0.05+0.01=0.060000000000000005

解释:很多编程语言在计算算数运算,容易导致精度丢失。而JavaBigDecimal类提供了add()加、subtract()减、multiply()乘、divide()除、pow()乘方等方法对精度浮点数进行常规计算。看例子:

BigDecimal f1=new BigDecimal("0.01");//String类型

BigDecimal f2=new BigDecimal("0.05");//String类型

BigDecimal f3=new BigDecimal(0.05);//double类型

System.out.println(f1.add(f2));//输出:0.06

System.out.println(f1.add(f3));//输出:0.06000000000000000277555756156289135105907917022705078125

结论:f2转的是String类型,f3转的是double类型,因此一定要使用String对象作为构造器参数,而不是直接使用double数字

Calendar类:因为Date是一个设计相当糟糕的类,因此Java官方推荐尽量少用Date的构造器方法,而是使用Calendar类。Calendar是一个抽象类,所以不能使用构造器来创建对象,但它提供了几个静态的getInstance()方法来获取Calendar对象。Calendar类提供大量方法:

void add(int field,int amount);根据日历的规则,为给定的日历字段添加或减少指定时间量;

int get(int field)返回指定日历字段的值;

void set(int year,int month,int date,int hour,int minute,int second)设置Calendar对象的年、月、日、时、分、秒6个字段的值。值得指出的是,月份不是从1开始,而是从0开始计算的,所以设置8月时,用7而不是8例子:

Calendar c = Calendar.getInstance();System.out.print(c.get(Calendar.YEAR)+"年");//输出 2016

System.out.print(c.get(Calendar.MONTH)+1+"月");//输出 10月,如果月份不+1,则是9,因此从0开始计算。

c.set(2017, 10, 24, 23, 05, 50);//设置值    

System.out.print(c.get(Calendar.YEAR)+"年");//输出2017

System.out.print(c.get(Calendar.MONTH)+"月");//输出10月,如果+1的话,则是11月。输出的是设置的值,不会变。

c.add(Calendar.YEAR, 1);//年份向后推一年即+1   

c.roll(Calendar.MONTH, -1);//月份向前推一个月即-1

介绍add()方法和roll()方法:

add()方法:规则①,当被修改的字段超过它允许范围,会发生进位,即上一级也会增加。比如:c.set(2007,7,23);c.add(Calendar.MONTH,6);//结果会变成 2008-1-23

如果下一级字段也需要改变,那么该字段也会修正到最小值:

c.set(2007,8,30);c.add(Calendar.MONTH,6);//结果会变成 2008-2-29 2月份没有31号,最大是29。?但是我的机器上跑出来的结果是:2008年2月30日 ! 而且如果是:c.set(2007, 8,33);跑出来的结果是:2008年3月3日!太神奇。

设置Calendar的容错性:如果传入一个不合法的参数,比如月份13,会导致年份+1,这时需要设置容错性,让它对参数进行严格检查:

c.setLenient(false);设置之后,如果有参数,将导致运行异常。但是2008-2-30还是没解决?!

④正则表达式:

x

字符x代表任何合法的字符

\0mnn

八进制数0mnn所代表的字符

\xhh

十六进制值0xhh所表示的字符

\uhhhh

十六进制0xhhhh所表示的Unicode字符,即ASCII

\t

制表符(‘\u0009’)

\n

换行符(‘\u000A’)

\r

回车符(‘\u000D’)

\f

换页符(‘\u000C’)

\a

报警符(‘\u0007’)

\e

Escape符(‘\u001B’)

\cx

x对应的控制符,如\cM匹配Ctrl-Mx必须是A~Za~z

  

$

匹配一行的结尾

^

匹配一行的开头

()

标记子表达式的开始和结束位置

[]

用于标记前面子表达式的开始和结束位置

{}

用于标记前面子表达式的出现频度

*

指定前面子表达式可以出现零次或多次

+

指定前面子表达式可以出现一次或多次

?

指定前面子表达式可以出现零次或一次

.

匹配除换行符\n之外的任何单字符

\

用于转义下一个字符,或指定八进制、十六进制字符

|

指定两项之间任选一项。

 上面的特殊字符表,如果要匹配本身,请使用转义字符\”写在前面,如需匹配“\”,请使用“\\”。表中紫色部分,说明匹配一个字符之后,到匹配下一个字符,都需要使用“\”写在前面

 

预定义字符

.

可以匹配任何字符

\d

匹配0~9的所有数字

\D

匹配非数字

\s

匹配所有的空白字符,包括空格,制表符,回车符,换页符,换行符等

\S

匹配所有的非空白字符

\w

匹配所有的单词字符,包括0~9所有数字,26个英文字符和下划线(_

\W

匹配所有的非单词字符

上面的7个预定义字符其实很容易记忆,d——是digit的意思,代表数字;sspace意思,代表空白;wword意思,代表单词。它们的大写形式刚好和它们相反。

c\\wt”:匹配如“c2tcatcbtc9t”等字符串。  “\\d\\d\\d-\\d\\d\\d-\\d\\d\\d\\d”:匹配如“000-000-0000”的数字。但是上面除了匹配abc之外的所有小写字母,或者匹配中文字符,预定义字符就无能为力了。这时候需要使用方括号表达式。

方括号表达式

说明

表示枚举

例如[abc],表示abc其中任意一个字符。

表示范围-

例如[a-f],表示a~f范围内任意字符;[\\u0041-\\u0056]表示16进制某些范围;[a-cx-z]表示a~cx~z范围内的任意字符

表示求否:^

例如[^abc],表示非abc的任意字符,[^a-f],表示非a~f范围内的任意字符

表示“与”运算:&&

例如[a-z &&[def]],求a~z[def]的交集,表示def[a-z&&[^bc]]表示a~z范围内的所有字符,除了bc之外,即[ad-z]

表示“并”运算

并运算与前面的枚举类似,例如[a-d[m-p]]表示[a-dm-p]

正则表达式还支持圆括号表达式,用于将多个表达式组成一个子表达式,圆括号可以使用或运算符(|)。例如“((public))|(protected)|(private)”用于匹配java的三个访问控制符其中一个。

边界匹配符

说明

^

行的开头

$

行的结尾

\b

单词的边界

\B

非单词的边界

\A

输入的开头

\G

前一个匹配的结尾

\Z

输入的结尾,仅用于最后的结束符

\z

输入的结尾

看前面的例子,验证号码,太繁琐。正则表达式支持的数量标识符有如下几种模式:

Greedy(贪婪模式):数量表示符默认采用贪婪模式,除非另有表示。贪婪模式的表达式会一直匹配下去,直到无法匹配为止。

Reluctant(勉强模式):用问号后缀(?)表示,它只会匹配最少的字符,也称为最小匹配模式。

Possessive(占有模式):用加好后缀(+)表示,目前只有Java支持占有模式,通常比较少用。

贪婪模式

勉强模式

占用模式

说明

X?

X??

X?+

X表达式出现零次或一次

X*

X*?

X*+

X表达式出现0次或多次

X+

X+?

X++

X表达式出现一次或多次

X{n}

X{n}?

X{n}+

X表达式出现n

X{n,}

X{n,}?

X{n,}+

X表达式至少出现n

X{n,m}

X{n,m}?

X{n,m}+

X表达式最少出现n次,最多出现m

使用正则表达式:PatternMatcher来使用正则表达式,如:

Pattern p=Pattern.compile("a*b");//使用Pattern对象创建Matcher对象:Matcher m=p.matcher("aaaaab");

boolean b=m.matches();//返回true

通过Matcher类的find()group()方法可以从目标字符串中一次取出特定子串,例如互联网的网络爬虫。

Pattern类是不可变类,可提供多个并发线程安全使用。Matcher类提供了如下几个常用方法:

find():返回目标字符串中是否包含与Pattern匹配的子串

group():返回上一次与Pattern匹配的子串

start():返回上一次与Pattern匹配的子串在目标字符串中的开始位置

end():返回上一次与Pattern匹配的子串在目标字符串的结束位置加1

lookingAt():返回目标字符串前面部分与Pattern是否匹配。

matches():返回整个目标字符串与Pattern是否匹配

reset():将现有的Matcher对象应用于一个新的字符序列。

一个例子:String str="招聘:13588956521,卖小狗:15652155555,出售二手老婆:15685965656";

//该正则表达式只抓取13X和15X段的手机号

Matcher m=Pattern.compile("((13\\d)|(15\\d))\\d{8}").matcher(str);

while(m.find()){System.out.println(m.group());}//将输出字符串里的所有号码。

其中,Pattern类的compile()方法创建一个Pattern对象,并用它建立一个Matcher对象

实际上,Matcher类还提供一个replaceFirst()方法,该方法只替换第一个匹配的子串,实际上,String类中也提供了replaceAll() replaceFirst()  split()等方法,来进行正则表达式来替换和分割。

⑤使用SimpleDateFormat格式化日期:

SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日hh:mm:ss");

Date dd=new Date();System.out.println(sdf.format(dd));//输出:2016年10月26日05:49:08

一个使用正则表达式的例子:

String strArr = "A1B2C3D4E5F6G7";int[] intArr = new int[7];Matcher m = Pattern.compile("\\d").matcher(strArr);

int i = 0;while (m.find()) {intArr[i] = Integer.parseInt(m.group().toString());i++;}

这样就把数字部分存放到了数组里。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

《疯狂Java讲义》读书笔记(四):Java基础类库 的相关文章

随机推荐