java必须精通第四课

java常用类库

1.Runtime类
在java中Runtime类表示运行时操作类,是一个封装了JVM进程的类,每一个JVM都对应着一个Runtime类的
实例,此实例由JVM运行时为实例化。Runtime是单例私有化设计,所以要取得Runtime实例通过以下方式:
Runtime run=Runtime.getRuntime();

Runtime实例方法

2.Runtime类与Process类
除了观察内存的的使用量之外,也可以直接使用Runtime类运行本机可执行程序。
例如执行记事本命令“notepad.exe”
public class Test2 {
	
	public static void main(String[] args) {
		Process pro=null;
		Runtime run=Runtime.getRuntime();
		try {
			pro=run.exec("notepad.exe"); //打开记事本应用程序
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		pro.destroy();
	}
}
2.国际化程序

要实现国际化程序只靠Locale类是不够的,还需要属性文件和ResourceBundle类的支持。所谓的属性文件是指后缀为.properties的文件,文件中的内容保存结构为“key-value”形式。
属性文件中保存真正要使用的文字信息,要访问这些属性文件可以使用ResourceBundle类来完成。
如果要实现java程序的国际化,必须通过三个类来完成:
1.java.util.Locale:用于表示一个国家语言类
2.java.util.ResurceBundle:用于访问资源文件
3.java.text.MessageFormat:格式化资源文件的占位字符串
这三个类的据图操作为:通过Locale类指定的区域编码,然后ResourceBundle根据Locale类指定的区域编码找到对应的资源文件,如果资源文件中存在动态文本,则使用MessageFormat进行格式化。

资源文件有时也成为了属性文件,可以直接使用java类集中提供的Properties类进行操作。
Locale的构造方法
ResourceBundle
ResourceBundle主要作用是读取属性文件,读取属性文件时,可以直接指定属性文件的名称(指定名称时不需要后缀)也可以根据Locale所指定的区域编码来选取指定的资源文件。
如果要使用ResourceBundle对象,则肯定直接通过ResourceBundle类中的静态方法getBundle()取得。

public class Test2 {
	
	public static void main(String[] args) {
		ResourceBundle rb=ResourceBundle.getBundle("chinese");
		String name=(String) rb.getString("name");
		System.out.println(name);
	}
}
// ResourceBundle是专门用来读取配置文件的工具类
// bundle只能读取properties类型的文件, 读取的时候只需要文件名, 不需要后缀
// bundle还提供了迭代的方法读取所有配置
找不到文件原因?
  没有找到需要加载的配置文件,因为配置文件必须放在src目录下面,
  如果放进了某个包下面,就必须添加包的名称到配置文件的路径名当中

properties
资源文件

public class Test2 {
	
	public static void main(String[] args) {
		
		Locale zhlocale=new Locale("zh","CN");//表示中国地区
		Locale enlocale=new Locale("en","US");//表示中国地区
		Locale frlocale=new Locale("fr","FR");//表示中国地区
		
		ResourceBundle chinese=ResourceBundle.getBundle("chinese",zhlocale);
		ResourceBundle english=ResourceBundle.getBundle("english",enlocale);
		ResourceBundle france=ResourceBundle.getBundle("france",frlocale);
		String name1=(String) chinese.getString("name");
		String name2=(String) english.getString("name");
		String name3=(String) france.getString("name");
		System.out.println(name1+name2+name3);
	}
}
结果:
你好HelloBonjour
System

System类是一些与系统相关的属性和方法,而且System类中所有的属性都是动态的。System常用方法

举例:获取本机全部环境属性
public class Test2 {
	
	public static void main(String[] args) {
		System.getProperties().list(System.out);
	}
}
结果(部分):
-- listing properties --
java.runtime.name=Java(TM) SE Runtime Environment
sun.boot.library.path=C:\Program Files\Java\jdk1.8.0_91\jre...
java.vm.version=25.91-b15
java.vm.vendor=Oracle Corporation
java.vendor.url=http://java.oracle.com/
path.separator=;
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
file.encoding.pkg=sun.io
user.script=
user.country=CN
sun.java.launcher=SUN_STANDARD
垃圾对象回收

java中有垃圾自动回收机制,可以不定期的释放java中的垃圾空间,System类中的gc()方法实际上是对Runtime类中的gc()方法的封装,功能与其相似。
如何对一个对象进行回收?
一个对象如果不再被任何栈内存所引用 ,那么此对象就可以称为垃圾对象,等待被回收。实际上等待的时间是不确定的。所以可以直接调用System.gc()方法进行垃圾回收。
在实际开发中,垃圾内存的释放基本都是由系统自动完成的,除非特殊情况,一般很少直接去调用gc()方法
如果一个对象在被回收之前要进行某些操作怎么办?
在Object有一个Object类里面没有finalize()方法,一个子类只需要覆写此方法,即可在释放对象前进行某些操作。

日期操作

在java中对于日期操作也提供了良好的支持,主要使用java.util包中的Date、Calendar以及java.text包中的SimpleDateFormat。

1.Date类
Date类是一个较简单的操作类,在使用中直接使用java.util.Date类的构造方法并进行输出就可以得到一个
完整的日期。
public class Test2 {
	
	public static void main(String[] args) {
		Date date=new Date();
				System.out.println(date);
	}
}
结果:
Tue Jul 16 15:48:47 CST 2019

从结果看,已经得到当前系统的日期,但是对于此日期的格式并不是很好,而且时间也不能精准到毫秒。
要想按照自己的格式显示时间可以使用Calendar类完成操作。

2.Calendar类
Calendar类可以取得时间到毫秒。但是这个类本身是一个抽象类,则必须依靠对象的多态性,通过子类进行父类
的实例化操作,Calendar的子类是GregorianCalendar类。

Calendar类的常量
Calendar类中的方法

public class Test2 {
	public static void main(String[] args) {
		Calendar calendar=null;
		calendar=new GregorianCalendar();
		System.out.println(calendar.get(Calendar.YEAR));
		System.out.println(calendar.get(calendar.MONTH));
		System.out.println(calendar.get(calendar.DAY_OF_MONTH));
		System.out.println(calendar.get(calendar.HOUR));
		System.out.println(calendar.get(calendar.MINUTE));
		System.out.println(calendar.get(calendar.SECOND));
	}
}
结果:
2019
6
16
4
1
10

以上程序通过子类GregorianCalendar实例化Calendar()类,然后通过Calendar类中的各种常量和方法
取得系统当前时间。但是按照以上方法取得代码会比较复杂,所以在java中又提供了其他日期类。

3.DateFormat类
java.util.Date类中实际上取得的时间是一个非常正确的时间,但是因为其显示的格式不理想,
所以无法符合中国人的习惯要求,所以就以DateFormat类来格式化操作。
DateFormate和MessageFormat类都属于format类的子类
DateFormat类是一个抽象类,所以肯定无法直接实例化,但是在此抽象类中提供了一个静态方法,
可以直接取得本类实例。

DateFormat常用方法

public class Test2 {
	public static void main(String[] args) {
		DateFormat df1=null;
		DateFormat df2=null;
		df1=DateFormat.getDateInstance(); //取得日期
		df2=DateFormat.getDateTimeInstance(); //取得日期时间
		System.out.println(df1.format(new Date()));
		System.out.println(df2.format(new Date()));
		
	}
}
结果:
2019-7-16
2019-7-16 17:32:10

4.SimpleDateFormat类
将一种日期格式转换为另一种日期格式

常用方法
样例

public class Test2 {
	public static void main(String[] args) {
		String dateS="2019-07-16 17:32:10";
		String par1="yyyy-MM-dd hh:mm:ss";
		String par2="yyyy年MM月dd日 hh时mm分ss秒";
		SimpleDateFormat sdf1=new SimpleDateFormat(par1);
		SimpleDateFormat sdf2=new SimpleDateFormat(par2);
		
		Date d=null;
		try {
			d=(Date) sdf1.parse(dateS);
			System.out.println(sdf1.parse(dateS));
			System.out.println(sdf2.format(d));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

结果:
Tue Jul 16 17:32:10 CST 2019
2019年07月16日 05时32分10秒

SimpleDateFormat类经常用于将String变为Date数据类型。
4.Random类
Random类是随机数产生类,可以指定一个随机数范围,然后任意产生此范围中的数字

Random类中常用方法

public class Test2 {
	public static void main(String[] args) {
		Random r=new Random();
		System.out.println(r.nextInt(100));//随机产生不大于100的随机数
	}
}

NumberFormat常用方法

NumberFormat表示数字格式化类,即可以按照本地的风格习惯进行数字显示。
NumberFormat是一个抽象类。
public class Test2 {
	public static void main(String[] args) {
		NumberFormat nf=null;
		nf=NumberFormat.getInstance();
		System.out.println(nf.format(100000000));
		System.out.println(nf.format(10000.326));
	}
}
结果:
100,000,000
10,000.326

5.BigInteger类
当一个数字非常大时,则肯定无法使用基本的类型接收,所以最早碰到大数字时往往会使用String类进行接收,
然后再采用拆分的方式进行计算,但操作非常麻烦,所以在java中为了解决这样的难题提供了BigInteger类,
BigInteger类表示大整数类。如果在操作一个整型数据已经超过了整数的最大类型长度long,数据无法装入。
此时可以使用BigInteger类操作。

public class Test2 {
	public static void main(String[] args) {
		BigInteger bi1=new BigInteger("123456789");
		BigInteger bi2=new BigInteger("987654321");
		System.out.println(bi1.add(bi2));
		System.out.println(bi2.subtract(bi1));
		System.out.println(bi2.multiply(bi1));
		System.out.println(bi2.divide(bi1));
		
	}
}

结果:
1111111110
864197532
121932631112635269
8

BigInteger类常用方法

6.BigDecimal类
对于不需要任何准确计算精度的数字可以直接使用float或double,但是如果需要精度计算结果,则必须
使用BigDecimal类,而且使用BigDecimal可以进行大量操作。
可以进行四舍五入等。

BigDecimal常用方法

对象克隆技术

java支持对象的克隆技术,直接使用Object类中clone方法即可
protected object clone() throws CloneNotSupportedException
以上方法是受保护类型,所以在子类中必须覆写此方法,而且覆写之后应该扩大访问权限,这样才能被外部调用,但是具体的克隆方法实现还是在Object中,所以在覆写的方法中只需要调用Object类中的clone()方法即可完成操作。而且对象所在的类必须实现Cloneable接口才可以完成对象的克隆操作。

public class Test2 implements Cloneable{
	
	private String name=null;
	
	public Test2(String name) {
		this.name=name;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public Object clone() throws CloneNotSupportedException {
		return super.clone();
	}
	public String toString() {
		return "姓名"+ this.name;
	}
}

public static void main(String[] args) throws CloneNotSupportedException {
	Test2 ts1=new Test2("张三");
	Test2 ts2=(Test2) ts1.clone();
	ts2.setName("李四");
	System.out.println("原始对象---"+ts1);
	System.out.println("克隆之后的对象---"+ts2);
	System.out.println("原始对象---"+ts1.getName());
	System.out.println("克隆之后的对象---"+ts2.getName());
	if(ts1==ts2) {
		System.out.println("true");
	}else {
		System.out.println("false");
	}
	}
	
}

结果:
原始对象---姓名张三
克隆之后的对象---姓名李四
原始对象---张三
克隆之后的对象---李四
false

可以看出来并不是一个对象。
7.Comparable类
比较器的基本应用:
数组可以使用java.util.Arrays类进行数组的排序操作,而且Arrays类中sort方法被重载多次,可以对
任意类型的数组进行排序,排列时会根据数值的大小进行排序,同样此类也可以对Object进行排序,
但是要使用此方法排序也是要有要求的,即对象所在的类必须实现Comparable接口,此接口用于
指定对象的排序规则。
public interface Comparable<T>{
	public int 	compareTo(T o);
}
可以看出来,在Comparable接口中也使用了java泛型技术。其中只有一个compareTo方法,此方法返回一个
int数据,值有以下三种
1:表示大于
-1:表示小于
0:表示等于

设计一个学生类,此类包含姓名、年龄、成绩,并产生一个对象数组,按成绩由高到低排序,
如果成绩相等,则按照年龄由低到高排序。
public class Student implements Comparable<Student>{
	
	private String name;
	private int age;
	private int score;
	
	public Student(String name,int age,int score) {
		this.name=name;
		this.age=age;
		this.score=score;
	}
	public String toString() {
		return name+"---"+age+"---"+score;
	}
	

	@Override
	public int compareTo(Student o) {
		// TODO Auto-generated method stub
		if(this.score>o.score) {
			return -1;
		}else if(this.score<o.score) {
			return 1;
		}else {
			if(this.age<o.age) {
				return -1;
			}else if(this.age>o.age) {
				return 1;
			}else {
				return 0;
			}
		}
	}
	
}

public class Test3{
	
public static void main(String[] args) {
	
	Student st[]= {new Student("张三", 10, 100),
			       new Student("李四", 19, 60),
			       new Student("王五", 5, 60)};
	Arrays.sort(st);
	for(int i=0;i<st.length;i++) {
		System.out.println(st[i]);
		}
	}	
}

结果:
张三---10---100
王五---5---60
李四---19---60

二叉树原理图

取结果的时候,先取左侧的树(从最左侧节点开始取),取根节点,再从右侧去最左侧几点。反复即可

/*二叉树排序*/

	/*假设通过二叉树对如下10个随机数进行排序
	67,7,30,73,10,0,78,81,10,74
	排序的第一个步骤是把数据插入到该二叉树中
	插入基本逻辑是,小、相同的放左边,大的放右边
	1. 67 放在根节点
	2. 7 比 67小,放在67的左节点
	3. 30 比67 小,找到67的左节点7,30比7大,就放在7的右节点
	4. 73 比67大, 放在67得右节点
	5. 10 比 67小,找到67的左节点7,10比7大,找到7的右节点30,10比30小,放在30的左节点。
	...
	...
	6. 10比67小,找到67的左节点7,10比7大,找到7的右节点30,10比30小,找到30的左节点10,
	7. 10和10一样大,放在左边*/
public class Node{
		//左节点
	 public Node leftNode;
	    // 右子节点
	    public Node rightNode;
	  
	    // 值
	    public Object value;
	  
	    // 插入 数据的方法
	    public void add(Object v) {
	        // 如果当前节点没有值,就把数据放在当前节点上
	        if (null == value)
	            value = v;
	  
	        // 如果当前节点有值,就进行判断,新增的值与当前值的大小关系
	        else {
	            // 新增的值,比当前值小或者相同
	             
	            if ((Integer) v -((Integer)value) <= 0) {
	                if (null == leftNode)
	                    leftNode = new Node();
	                leftNode.add(v);
	            }
	            // 新增的值,比当前值大
	            else {
	                if (null == rightNode)
	                    rightNode = new Node();
	                rightNode.add(v);
	            }
	  
	        }
	  
	    }
	    
	    // 中序遍历所有的节点
	    public List<Object> values() {
	        List<Object> values = new ArrayList<>();
	  
	        // 左节点的遍历结果
	        if (null != leftNode)
	            values.addAll(leftNode.values());
	  
	        // 当前节点
	        values.add(value);
	  
	        // 右节点的遍历结果
	        if (null != rightNode)
	  
	            values.addAll(rightNode.values());
	  
	        return values;
	    }
	 
	    
	    public static void main(String[] args) {
	    	  
	        int randoms[] = new int[] { 67, 7, 30, 73, 10, 0, 78, 81, 10, 74 };
	  
	        Node roots = new Node();
	        for (int number : randoms) {
	            roots.add(number);
	        }
	        System.out.println("数据插入二叉树并排序完成,接下来完成遍历输出:");
	        System.out.println(roots.values());
	    }
}
观察者设计模式

就像所有购房者都关注房子的价格一样
java通过Observable和Observer接口轻松实现以上功能。
Observable类常用方法

public class House extends Observable{
	private float price;
	public House(float price) {
		this.price=price;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		super.setChanged(); //设置变化点
		super.notifyObservers(price);  //通知所有观察者价格变化
		this.price = price;
	}
	
	public String toString(){
		return "房子的价格为"+price;
	}
	
}

public class HousePriceobeserve implements Observer{
	private String name;
	
	public HousePriceobeserve(String name) {
		this.name=name;
	}
	@Override
	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		if(arg instanceof Float) {
			System.out.println(this.name+"观察者看到的价格为"+arg);
		}
	}
}

public class Test3{
public static void main(String[] args) {
	House h=new House(10000);
	HousePriceobeserve hp1=new HousePriceobeserve("购房者A");
	HousePriceobeserve hp2=new HousePriceobeserve("购房者B");
	HousePriceobeserve hp3=new HousePriceobeserve("购房者C");
	h.addObserver(hp1);
	h.addObserver(hp2);
	h.addObserver(hp3);
	System.out.println(h);
	h.setPrice(13000);
	System.out.println(h);
  	·}	
}
结果:
房子的价格为10000.0
购房者C观察者看到的价格为13000.0
购房者B观察者看到的价格为13000.0
购房者A观察者看到的价格为13000.0
房子的价格为13000.0

从程序的运行结果来看,多个观察者都在观察价格的变化,只要价格一有变化,则所有的观察者立刻能发现。
Pattern类和Matcher类

如果程序中应用正则表达式则必须依靠Pattern类和Matcher类,这两个类都在java.util.regex包中定义,Pattern主要作用是正则规范,Matcher类主要是执行规范,验证一个字符串是否符合规范。
常用的正则规范
数量表示
在这里插入图片描述

验证一个字符串是否是合法日期
public class Test3{
	
public static void main(String[] args) {
	String str="2019-07-17";
	String pat="\\d{4}-\\d{2}-\\d{2}";
	
	Pattern p=Pattern.compile(pat);
	Matcher m=p.matcher(str);
	if(m.matches()) {
		System.out.println("日期合法");
	}else {
		System.out.println("日期不合法");
	}
}

结果:
日期合法

Pattern也可以直接对字符串进行拆分
public class Test3{
	
public static void main(String[] args) {
	String str="Abco15362jiflkcjf585flfp4546fkjfk";
	String pat="\\d";
	
	Pattern p=Pattern.compile(pat);
	String[] m=p.split(str);
	for(int i=0;i<m.length;i++) {
		System.out.println(m[i]);
	}
}	
}
定时调度

Timer类是一种线程设施,可以用来实现在某一时间或某一段时间后安排某一个任务执行一次或定期重复执行,该功能要与TimerTask配合使用。TimeTask类用来实现由Timer安排的一次或重复执行的某一任务。
每个Timer对象对应的是一个线程,因此计时器所执行的任务应该迅速完成,否则可能会有延迟或后续任务的执行,而这些后续任务就有可能堆在一起,等到任务完成后,才能快速连续执行。

public class MyTask extends TimerTask{
	@Override
	public void run() {
		// TODO Auto-generated method stub
		SimpleDateFormat sdf=null;
		sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
		System.out.println(sdf.format(new Date()));
	}
}

public class Test3{
	
public static void main(String[] args) {
	Timer time=new Timer(); //建立Timer对象
	MyTask my=new MyTask(); //定义任务
	time.schedule(my, 1000,3000); //设置任务执行。一秒后开始。每两秒重复
	}	
}

内容阶段总结:
1.在一个字符串内容需要频繁修改时,使用StringBuffer可以提高性能,因为StringBuffer内容可以改变,而String内容不可以改变。
2.StringBuffer提供了大量的字符串方法,如增加、替换、插入等
3.Runtime表示运行时在一个JVM中只存在一个Runtime,所以要想取得Runtime类对象,直接使用Runtime类中提供的静态方法getRuntime即可。
4.国际化实现的基本原理为:所有的语言信息以key-value的形式存储在文件中,程序通过key找到对应的Value,根据其所设置的国家Locale对象不同,找到资源文件也不同,要想实现国际化必须依靠Locale和ResourceBundle两个类共同完成。
5.System类是系统类,可以取得系统的相关信息,使用System.gc()可以强制的进行垃圾回收操作。
调用此方法实际及时调用Runtime类中的gc()方法。
6.Format类为格式化操作类,主要的三个子类是:MessageFormat,NumberFormat,DateFormat
7.使用Date类可以方便的取得时间,但取得的时间格式不符合地域风格,所以可以使用SimpleDateFormat类进行日期格式化。
8.处理大数字可以使用BigInteger和BigDecimal类,当需要精确到小数点操作位时,应该使用BigDecimal类
9.通过Random类可以取得指定范围的随机数。
10.如果一个类的对象要被克隆,则此对象所在的类必须实现Cloneable接口。
11.要对一组对象进行排序,则必须使用比较器,比较器接口Comparable中定义了compareTo()的比较方法,用来设置比较规则。
12.正则表达式是开发中最常验证的一种方法,String类中的replace All(),split(),matches()方法都是对正则表达式的支持。
13.可以用Time和TimeTask类完成系统的定时操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值