Java常用类库(二)
-----------------------
Math与Random类
Math类表示数学操作类,在Math类中的方未予都是静态方法,直接使用“类.方法名称()”形式调用即可。
实例:
- public class MathDemo01{
- public static void main(String args[]){
- // Math类中的方法都是静态方法,直接使用“类.方法名称()”的形式调用即可
- System.out.println("求平方根:" + Math.sqrt(9.0)) ;
- System.out.println("求两数的最大值:" + Math.max(10,30)) ;
- System.out.println("求两数的最小值:" + Math.min(10,30)) ;
- System.out.println("2的3次方:" + Math.pow(2,3)) ;
- System.out.println("四舍五入:" + Math.round(33.6)) ;
- }
- };
Random类
Random类主要是产生随机数,可以产生一个指定范围的随机数,Random类是定义在java.util包中的类。
实例:
- import java.util.Random ;
- public class RandomDemo01{
- public static void main(String args[]){
- Random r = new Random() ; // 实例化Random对象
- for(int i=0;i<10;i++){
- System.out.print(r.nextInt(100) + "\t") ;
- }
- }
- };
NumberFormat类
NuberFormat的基本使用:此类主要完成数字的格式化显示。
实例:
- import java.text.* ;
- public class NumberFormatDemo01{
- public static void main(String args[]){
- NumberFormat nf = null ; // 声明一个NumberFormat对象
- nf = NumberFormat.getInstance() ; // 得到默认的数字格式化显示
- System.out.println("格式化之后的数字:" + nf.format(10000000)) ;
- System.out.println("格式化之后的数字:" + nf.format(1000.345)) ;
- }
- };
DecimalFormat的基本使用:DecimalFormat也是Format的一个子类,主要的作用是用来格式化数字使用,当然,在格式化数字的时候要比直接使用NumberFormat更加方便,因为可以直接指按用户自定义的方式进行格式化操作,与之前SimpleDateFormat类似。
实例:
- import java.text.* ;
- class FormatDemo{
- public void format1(String pattern,double value){ // 此方法专门用于完成数字的格式化显示
- DecimalFormat df = null ; // 声明一个DecimalFormat类的对象
- df = new DecimalFormat(pattern) ; // 实例化对象,传入模板
- String str = df.format(value) ; // 格式化数字
- System.out.println("使用" + pattern
- + "格式化数字" + value + ":" + str) ;
- }
- };
- public class NumberFormatDemo02{
- public static void main(String args[]){
- FormatDemo demo = new FormatDemo() ; // 格式化对象的类
- demo.format1("###,###.###",111222.34567) ;
- demo.format1("000,000.000",11222.34567) ;
- demo.format1("###,###.###¥",111222.34567) ;
- demo.format1("000,000.000¥",11222.34567) ;
- demo.format1("##.###%",0.345678) ;
- demo.format1("00.###%",0.0345678) ;
- demo.format1("###.###\u2030",0.345678) ;
- }
- };
大数操作类(BigInter、BigDecimal)
大数操作,一般是指在超出long、double类型能够存放的范围时使用。
操作整型:BigInteger
操作小数:BigDecimal
BigDecimal实例:
- import java.math.* ;
- class MyMath{
- public static double add(double d1,double d2){ // 进行加法计算
- BigDecimal b1 = new BigDecimal(d1) ;
- BigDecimal b2 = new BigDecimal(d2) ;
- return b1.add(b2).doubleValue() ;
- }
- public static double sub(double d1,double d2){ // 进行减法计算
- BigDecimal b1 = new BigDecimal(d1) ;
- BigDecimal b2 = new BigDecimal(d2) ;
- return b1.subtract(b2).doubleValue() ;
- }
- public static double mul(double d1,double d2){ // 进行乘法计算
- BigDecimal b1 = new BigDecimal(d1) ;
- BigDecimal b2 = new BigDecimal(d2) ;
- return b1.multiply(b2).doubleValue() ;
- }
- public static double div(double d1,double d2,int len){ // 进行乘法计算
- BigDecimal b1 = new BigDecimal(d1) ;
- BigDecimal b2 = new BigDecimal(d2) ;
- return b1.divide(b2,len,BigDecimal.ROUND_HALF_UP).doubleValue() ;
- }
- public static double round(double d,int len){ // 进行四舍五入
- BigDecimal b1 = new BigDecimal(d) ;
- BigDecimal b2 = new BigDecimal(1) ;
- return b1.divide(b2,len,BigDecimal.ROUND_HALF_UP).doubleValue() ;
- }
- };
- public class BigDecimalDemo01{
- public static void main(String args[]){
- System.out.println("加法运算:" + MyMath.round(MyMath.add(10.345,3.333),1)) ;
- System.out.println("减法运算:" + MyMath.round(MyMath.sub(10.345,3.333),3)) ;
- System.out.println("乘法运算:" + MyMath.round(MyMath.mul(10.345,3.333),2)) ;
- System.out.println("除法运算:" + MyMath.div(10.345,3.333,3)) ;
- }
- };
BigInteger实例:
- import java.math.BigInteger ;
- public class BigIntegerDemo01{
- public static void main(String args[]){
- BigInteger bi1 = new BigInteger("123456789") ; // 声明BigInteger对象
- BigInteger bi2 = new BigInteger("987654321") ; // 声明BigInteger对象
- System.out.println("加法操作:" + bi2.add(bi1)) ; // 加法操作
- System.out.println("减法操作:" + bi2.subtract(bi1)) ; // 减法操作
- System.out.println("乘法操作:" + bi2.multiply(bi1)) ; // 乘法操作
- System.out.println("除法操作:" + bi2.divide(bi1)) ; // 除法操作
- System.out.println("最大数:" + bi2.max(bi1)) ; // 求出最大数
- System.out.println("最小数:" + bi2.min(bi1)) ; // 求出最小数
- BigInteger result[] = bi2.divideAndRemainder(bi1) ; // 求出余数的除法操作
- System.out.println("商是:" + result[0] +
- ";余数是:" + result[1]) ;
- }
- };
对象克隆技术
对象克隆:将对象完整的复制成另一个对象,必须依靠Object类
实例:
- class Person implements Cloneable{ // 实现Cloneable接口表示可以被克隆
- private String name ;
- public Person(String name){
- this.name = name ;
- }
- public void setName(String name){
- this.name = name ;
- }
- public String getName(){
- return this.name ;
- }
- public String toString(){
- return "姓名:" + this.name ;
- }
- public Object clone()
- throws CloneNotSupportedException
- {
- return super.clone() ; // 具体的克隆操作由父类完成
- }
- };
- public class CloneDemo01{
- public static void main(String args[]) throws Exception{
- Person p1 = new Person("张三") ;
- Person p2 = (Person)p1.clone() ;
- p2.setName("李四") ;
- System.out.println("原始对象:" + p1) ;
- System.out.println("克隆之后的对象:" + p2) ;
- }
- };
比较器
Comparable接口的作用
之前Arrays类中存在sort()方法,此方法可以直接对对象数组进行排序
Coparable接口可以直接使用java.util.Arrays类进行数组的排序操作,但对象所在的类必须实现Comparable接口,用于指定排序接口。
实例:要求:定义一个学生类,里面有姓名、年龄、成绩三个属性,要求按成绩排序,如果成绩相等,则按照年龄由低到高排序
代码:
- class Student implements Comparable<Student> { // 指定类型为Student
- private String name ;
- private int age ;
- private float score ;
- public Student(String name,int age,float score){
- this.name = name ;
- this.age = age ;
- this.score = score ;
- }
- public String toString(){
- return name + "\t\t" + this.age + "\t\t" + this.score ;
- }
- public int compareTo(Student stu){ // 覆写compareTo()方法,实现排序规则的应用
- if(this.score>stu.score){
- return -1 ;
- }else if(this.score<stu.score){
- return 1 ;
- }else{
- if(this.age>stu.age){
- return 1 ;
- }else if(this.age<stu.age){
- return -1 ;
- }else{
- return 0 ;
- }
- }
- }
- };
- public class ComparableDemo01{
- public static void main(String args[]){
- Student stu[] = {new Student("张三",20,90.0f),
- new Student("李四",22,90.0f),new Student("王五",20,99.0f),
- new Student("赵六",20,70.0f),new Student("孙七",22,100.0f)} ;
- java.util.Arrays.sort(stu) ; // 进行排序操作
- for(int i=0;i<stu.length;i++){ // 循环输出数组中的内容
- System.out.println(stu[i]) ;
- }
- }
- };
实际上比较器的排序原理 就是二叉树的排序算法。
基本原里:使用第一个元素作为根节点,之后如果后面的内容比根节点要小,则放在左子树如果内容比根节点内容大,则放在右子树
手动完成二叉树算法:
- class BinaryTree{
- class Node{ // 声明一个节点类
- private Comparable data ; // 保存具体的内容
- private Node left ; // 保存左子树
- private Node right ; // 保存右子树
- public Node(Comparable data){
- this.data = data ;
- }
- public void addNode(Node newNode){
- // 确定是放在左子树还是右子树
- if(newNode.data.compareTo(this.data)<0){ // 内容小,放在左子树
- if(this.left==null){
- this.left = newNode ; // 直接将新的节点设置成左子树
- }else{
- this.left.addNode(newNode) ; // 继续向下判断
- }
- }
- if(newNode.data.compareTo(this.data)>=0){ // 放在右子树
- if(this.right==null){
- this.right = newNode ; // 没有右子树则将此节点设置成右子树
- }else{
- this.right.addNode(newNode) ; // 继续向下判断
- }
- }
- }
- public void printNode(){ // 输出的时候采用中序遍历
- if(this.left!=null){
- this.left.printNode() ; // 输出左子树
- }
- System.out.print(this.data + "\t") ;
- if(this.right!=null){
- this.right.printNode() ;
- }
- }
- };
- private Node root ; // 根元素
- public void add(Comparable data){ // 加入元素
- Node newNode = new Node(data) ; // 定义新的节点
- if(root==null){ // 没有根节点
- root = newNode ; // 第一个元素作为根节点
- }else{
- root.addNode(newNode) ; // 确定是放在左子树还是放在右子树
- }
- }
- public void print(){
- this.root.printNode() ; // 通过根节点输出
- }
- };
- public class ComparableDemo03{
- public static void main(String args[]){
- BinaryTree bt = new BinaryTree() ;
- bt.add(8) ;
- bt.add(3) ;
- bt.add(3) ;
- bt.add(10) ;
- bt.add(9) ;
- bt.add(1) ;
- bt.add(5) ;
- bt.add(5) ;
- System.out.println("排序之后的结果:") ;
- bt.print() ;
- }
- };
另一种比较器:Comparator
如果一个类已经开发完成,但是在此类建立的初期并没有实现Comparable接口,此时肯定是无法进行对象排序操作的,所以为了解决这样的问题,java又定义了另一具比较器的操作接口——Comparator。
实例:
- import java.util.* ;
- class Student{ // 指定类型为Student
- private String name ;
- private int age ;
- public Student(String name,int age){
- this.name = name ;
- this.age = age ;
- }
- public boolean equals(Object obj){ // 覆写equals方法
- if(this==obj){
- return true ;
- }
- if(!(obj instanceof Student)){
- return false ;
- }
- Student stu = (Student) obj ;
- if(stu.name.equals(this.name)&&stu.age==this.age){
- return true ;
- }else{
- return false ;
- }
- }
- public void setName(String name){
- this.name = name ;
- }
- public void setAge(int age){
- this.age = age ;
- }
- public String getName(){
- return this.name ;
- }
- public int getAge(){
- return this.age ;
- }
- public String toString(){
- return name + "\t\t" + this.age ;
- }
- };
- class StudentComparator implements Comparator<Student>{ // 实现比较器
- // 因为Object类中本身已经有了equals()方法
- public int compare(Student s1,Student s2){
- if(s1.equals(s2)){
- return 0 ;
- }else if(s1.getAge()<s2.getAge()){ // 按年龄比较
- return 1 ;
- }else{
- return -1 ;
- }
- }
- };
- public class ComparatorDemo{
- public static void main(String args[]){
- Student stu[] = {new Student("张三",20),
- new Student("李四",22),new Student("王五",20),
- new Student("赵六",20),new Student("孙七",22)} ;
- java.util.Arrays.sort(stu,new StudentComparator()) ; // 进行排序操作
- for(int i=0;i<stu.length;i++){ // 循环输出数组中的内容
- System.out.println(stu[i]) ;
- }
- }
- };
观察者设计模式
以购房者观注房价为例,结合java.util包中提供的Obeservable类和Observer接口实现。
代码:
- import java.util.* ;
- class House extends Observable{ // 表示房子可以被观察
- private float price ;// 价钱
- public House(float price){
- this.price = price ;
- }
- public float getPrice(){
- return this.price ;
- }
- public void setPrice(float price){
- // 每一次修改的时候都应该引起观察者的注意
- super.setChanged() ; // 设置变化点
- super.notifyObservers(price) ;// 价格被改变
- this.price = price ;
- }
- public String toString(){
- return "房子价格为:" + this.price ;
- }
- };
- class HousePriceObserver implements Observer{
- private String name ;
- public HousePriceObserver(String name){ // 设置每一个购房者的名字
- this.name = name ;
- }
- public void update(Observable o,Object arg){
- if(arg instanceof Float){
- System.out.print(this.name + "观察到价格更改为:") ;
- System.out.println(((Float)arg).floatValue()) ;
- }
- }
- };
- public class ObserDemo01{
- public static void main(String args[]){
- House h = new House(1000000) ;
- HousePriceObserver hpo1 = new HousePriceObserver("购房者A") ;
- HousePriceObserver hpo2 = new HousePriceObserver("购房者B") ;
- HousePriceObserver hpo3 = new HousePriceObserver("购房者C") ;
- h.addObserver(hpo1) ;
- h.addObserver(hpo2) ;
- h.addObserver(hpo3) ;
- System.out.println(h) ; // 输出房子价格
- h.setPrice(666666) ; // 修改房子价格
- System.out.println(h) ; // 输出房子价格
- }
- };
正则表达式
利用两段代码观察使用正则表达式的好处
不使用正则:
- public class RegexDemo01{
- public static void main(String args[]){
- String str = "1234567890" ; // 此字符串由数字组成
- boolean flag = true ; // 定义一个标记变量
- // 要先将字符串拆分成字符数组,之后依次判断
- char c[] = str.toCharArray() ; // 将字符串变为字符数组
- for(int i=0;i<c.length;i++){ // 循环依次判断
- if(c[i]<'0'||c[i]>'9'){ // 如果满足条件,则表示不是数字
- flag = false ; // 做个标记
- break ; // 程序不再向下继续执行
- }
- }
- if(flag){
- System.out.println("是由数字组成!") ;
- }else{
- System.out.println("不是由数字组成!") ;
- }
- }
- };
基本思路就是将字符串拆分,之后一个个进行比较验证,但是这样比较麻烦
使用正则表达式:
- import java.util.regex.Pattern ;
- public class RegexDemo02{
- public static void main(String args[]){
- String str = "1234567890" ; // 此字符串由数字组成
- if(Pattern.compile("[0-9]+").matcher(str).matches()){ // 使用正则
- System.out.println("是由数字组成!") ;
- }else{
- System.out.println("不是由数字组成!") ;
- }
- }
- };
Pattern、Matcher类
这两个类为正则的核心操作类,这两个类都定义在java.util.regex包中
Pattern为的主要作用是进行正则规范的编写。
而Matcher类主要是执行规范,验证一个字符串是否符合其规范。
实例:
- import java.util.regex.Pattern ;
- import java.util.regex.Matcher ;
- public class RegexDemo03{
- public static void main(String args[]){
- String str = "1983-07-27" ; // 指定好一个日期格式的字符串
- String pat = "\\d{4}-\\d{2}-\\d{2}" ; // 指定好正则表达式
- Pattern p = Pattern.compile(pat) ; // 实例化Pattern类
- Matcher m = p.matcher(str) ; // 实例化Matcher类
- if(m.matches()){ // 进行验证的匹配,使用正则
- System.out.println("日期格式合法!") ;
- }else{
- System.out.println("日期格式不合法!") ;
- }
- }
- };
String类对正则的支持
String对正则主要有三种支持方法:字符串匹配、字符串替换、字符串拆分
实例:
- import java.util.regex.Pattern ;
- import java.util.regex.Matcher ;
- public class RegexDemo06{
- public static void main(String args[]){
- String str1 = "A1B22C333D4444E55555F".replaceAll("\\d+","_") ;
- boolean temp = "1983-07-27".matches("\\d{4}-\\d{2}-\\d{2}") ;
- String s[] = "A1B22C333D4444E55555F".split("\\d+") ;
- System.out.println("字符串替换操作:" + str1) ;
- System.out.println("字符串验证:" + temp) ;
- System.out.print("字符串的拆分:") ;
- for(int x=0;x<s.length;x++){
- System.out.print(s[x] + "\t") ;
- }
- }
- };
定时调度
每当一段时间,程序会自动执行,称为定时调度。如果要使用定时调度,则必须保证程序始终运行着才可以,也就是说相当于定时调度是在程序之外又启动了一个新的线程。
Timer和TimerTask两个类完成定时调度
具体实例:
- // 完成具体的任务操作
- import java.util.TimerTask ;
- import java.util.Date ;
- import java.text.SimpleDateFormat ;
- class MyTask extends TimerTask{ // 任务调度类都要继承TimerTask
- public void run(){
- SimpleDateFormat sdf = null ;
- sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS") ;
- System.out.println("当前系统时间为:" + sdf.format(new Date())) ;
- }
- };
- import java.util.Timer ;
- public class TestTask{
- public static void main(String args[]){
- Timer t = new Timer() ; // 建立Timer类对象
- MyTask mytask = new MyTask() ; // 定义任务
- t.schedule(mytask,1000,2000) ; // 设置任务的执行,1秒后开始,每2秒重复
- }
- };