一、StringBuffer
在程序中可以使用String表示一个字符串的操作,但是String本身有如下特点:
·两种声明的方式,而且比较的时候靠equals()比较内容
·一个字符串的内容声明之后则不可改变
实际上String最要命的一个问题就是内容无法改变,但是这种功能在实际的开发中又不可能避免掉,此时就可以依靠StringBuffer类来完成这种功能。当字符串的内容需要被改变的时候就使用StringBuffer。
1、StringBuffer
如果现在需要将一个StringBuffer的类型变成String的话,则必须依靠toString()方法完成。
StringBuffer本身也属于一个类,所以里面也提供了很多的操作方法,但是这些方法大部分都与String类似。
但是StringBuffer也有许多自己的定义的方法,下面依次来看这些方法。
2、 字符串反转
·方法:public StringBuffer reverse()
public class ReverseDemo { public static void main(String[] args) { StringBuffer buf = new StringBuffer(); buf.append("hello world!!!"); System.out.println(buf.reverse()); } }
3、 字符串替换
·在String类中依靠replaceAll()方法完成替换
·方法:public StringBuffer replace(int start,int end,Stringstr)
|-需要指定替换的开始和结束位置
public class ReplaceDemo { public static void main(String[] args) { StringBuffer buf = new StringBuffer(); buf.append("hello world!!!"); System.out.println(buf.replace(0, buf.length(), "XXX")); } }
4、 插入内容
在使用append()方法的时候实际上所有的内容都是采用顺序的方式依次连接到后面的位置,也可以使用insert()方法完成在指定位置上的增加:public StringBuffer insert(int offset,char c),此方法被重载过很多次,可以插入各种数据类型。
public class InsertDemo { public static void main(String[] args) { StringBuffer buf = new StringBuffer(); buf.append("world!!!").insert(0, "hello"); System.out.println(buf); } }
二、Runtime
Runtime表示的是运行时的状态对象,即:每当有一个JVM进程产生的时候都会自动生成一个Runtime类的对象。但是在此类的定义中发现并没有构造方法的声明,很明显构造方法被私有化了,那么一旦构造方法被私有化,则内部一定会存在一个方法,可以取得本类的实例化对象:public static Runtime getRuntime()。
查询DOC文档的时候只要没有发现构造方法,则构造方法一定被私有化了,属于单例设计,则此时一定可以从类的内部找到一个static方法,取得本类的实例。
Runtime run = Runtime.getRuntime()
Runtime类可以取得一些系统的信息或者是建立一个新的进程。
1、取得系统信息
在Runtime类中定义了如下的三个方法,这些方法可以取得系统的内存使用情况:
·总共可以使用的内存:publiclong totalMemory()
·取得最大可用的内存:publiclong maxMemory()
·取得当前空余的内存:publiclong freeMemory()
在Java中对于垃圾收集实际上存在两种形式:
·手工回收:public void gc()
·自动回收:由系统完成
范例:观察垃圾收集之后的内存情况
public class RuntimeDemo01 { public static void main(String[] args) { Runtime run = Runtime.getRuntime(); System.out.println("** 1、maxMemory:" + run.maxMemory()); System.out.println("** 1、totalMemory:" + run.totalMemory()); System.out.println("** 1、freeMemory:" + run.freeMemory()); String str = ""; for (int x = 0; x < 10000; x++) { // 将产生大量的垃圾 str += x; } System.out.println("========= 产生垃圾之后============"); System.out.println("** 2、maxMemory:" + run.maxMemory()); System.out.println("** 2、totalMemory:" + run.totalMemory()); System.out.println("** 2、freeMemory:" + run.freeMemory()); run.gc(); // 垃圾收集 System.out.println("========= 垃圾收集之后============"); System.out.println("** 2、maxMemory:" + run.maxMemory()); System.out.println("**2、totalMemory:" + run.totalMemory()); System.out.println("** 2、freeMemory:" + run.freeMemory()); } }
2、运行本机程序
Runtime类最大的好处在于,可以直接运行本机的可执行程序,例如:运行:notepad.exe。
使用的方法:public Process exec(String command) throws IOException
此方法返回一个Process类的对象实例,那么此类可以用于进程的控制。
·销毁进程:public void destroy()
范例:观察程序的运行
public class RuntimeDemo02 { public static void main(String[] args) throws Exception { Runtime run = Runtime.getRuntime(); Process pro = run.exec("notepad.exe"); // 运行程序 Thread.sleep(2000); pro.destroy(); } }
三、System类
1、取得计算的时间
System类本身可以取得一个系统的当前时间,只是返回的时候按照long返回。
如果要想求出一个操作所花费的时间,采用的公式:结束时间-开始时间。
取得当前时间的方法:publicstatic long currentTimeMillis()
long start = System.currentTimeMillis();
2、垃圾回收与对象生命周期
在System类中定义了如下的方法:publicstatic void gc()。
当调用此方法的时候实际上就等同于调用了Runtime类中提供的gc()方法,两个是一样的。
当一个对象被回收之前实际上也是可以进行一些收尾工作,这些工作是依靠覆写Object类中的以下方法:
·方法:protected void finalize() throws Throwable
范例:观察对象的回收
class Person { public Person() { System.out.println("我出生了。。。"); } @Override protected void finalize() throws Throwable { System.out.println("我完了,我被回收了。。。"); } } public class ObjectGCDemo { public static void main(String[] args) { Person per = new Person(); per = null; System.gc(); // 手工回收 } }
一般一个对象都要经历以下的生命周期:
·加载->初始化->使用->回收->卸载
四、Math类
Math类本身表示的是数学的操作类,里面提供了各种各样的数学操作方法,例如:sin()等等。
方法:publicstaticlong round(double a),四舍五入
public class MathDemo { public static void main(String[] args) { System.out.println(Math.round(90.356)); System.out.println(Math.round(90.556)); } }
这个是将小数部分四舍五入只保存整数部分,那么如果要想进行准确的四舍五入的话,最早的做法是通过BigDecimal类完成的,这个类也称为大数操作类。
五、大数操作类
现在如果假设有两个数字非常的大,那么如果进行相乘的话,则肯定数字的会更大,此时,传统的数据类型已经无法装下了。
public class BigNumberDemo { public static void main(String[] args) { double d1 = Double.MAX_VALUE; double d2 = Double.MAX_VALUE; System.out.println(d1 * d2);//Infinity } }
这个时候数字已经太大了,所以根本就无法计算了,但是从现实世界中这种数字不可能避免。所以对于大数字的操作最早时候是通过字符串完成。所以在Java中为了解决这种大数的操作,提供了两个类:BigInteger、BigDecimal。
1、大整数操作类:BigInteger
BigInteger本身是一个类,里面提供了一些基本的计算方法,方法如下:
·构造:public BigInteger(String val)
·四则运算:
|-加法:public BigInteger add(BigInteger val)
|-减法:public BigInteger subtract(BigInteger val)
|-乘法:public BigInteger multiply(BigInteger val)
|-除法:public BigInteger divide(BigInteger val)、
public BigInteger[] divideAndRemainder(BigInteger val)
范例:观察大数字的操作
import java.math.BigInteger; public class BigIntegerDemo { public static void main(String[] args) { BigInteger bi1 = new BigInteger(Long.MAX_VALUE + ""); BigInteger bi2 = new BigInteger(Long.MAX_VALUE + ""); System.out.println("加法:" + bi1.add(bi2)); System.out.println("减法:" + bi1.subtract(bi2)); System.out.println("乘法:" + bi1.multiply(bi2)); System.out.println("除法:" + bi1.divide(new BigInteger("333"))); BigInteger res[] = bi1.divideAndRemainder(new BigInteger("333")); System.out.println("整数部分:" + res[0]); System.out.println("余数部分:" + res[1]); } }
2、大小数操作类:BigDecimal
对于BigDecimal本身和BigInteger是非常类似的,包括各个计算方法也都是非常类似的。
范例:观察四则运算
import java.math.BigDecimal; public class BigDecimalDemo { public static void main(String[] args) { BigDecimal bd1 = new BigDecimal(Double.MAX_VALUE); BigDecimal bd2 = new BigDecimal(Double.MAX_VALUE); System.out.println("加法:" + bd1.add(bd2)); System.out.println("减法:" + bd1.subtract(bd2)); System.out.println("乘法:" + bd1.multiply(bd2)); System.out.println("除法:" + bd1.divide(bd2)); } }
3、四舍五入操作
但是,在BigDecimal类中存在着一种除法操作,这种除法操作可以指定小数的保留位数:
·方法:publicBigDecimal divide(BigDecimal divisor,int scale,int roundingMode)
import java.math.BigDecimal; class MyMathRound { public static double round(double num, int scale) { BigDecimal bd = new BigDecimal(num); return bd.divide(new BigDecimal(1), scale, BigDecimal.ROUND_HALF_UP).doubleValue(); } public static BigDecimal round(String num, int scale) { BigDecimal bd = new BigDecimal(num); return bd.divide(new BigDecimal(1), scale, BigDecimal.ROUND_HALF_UP); } } public class RoundDemo { public static void main(String[] args) { System.out.println("四舍五入:" + MyMathRound.round(98.56137, 2)); System.out.println("四舍五入:" + MyMathRound.round(98.56637, 2)); System.out.println("四舍五入:" + MyMathRound.round("98.56637", 2)); } }
六、随机数
在java.util.Random类中主要的功能是用于产生随机数的。
范例:产生10个数字,都不大于100
import java.util.Random; public class RandomDemo { public static void main(String[] args) { Random rand = new Random(); for (int x = 0; x < 10; x++) { System.out.println(rand.nextInt(100)); } } }
七、SimpleDateFormat类
但是如果要进行格式化的话,需要指定一个格式化日期的模板:
·年(yyyy)、月(MM)、日(dd)、时(HH)、分(mm)、秒(ss)、毫秒(SSS)
1、format()-格式化日期
范例:格式化日期format()
import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDateFormatDemo01 { public static void main(String[] args) { // 准备好了一个要格式化的模板 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-ddHH:mm:ss.SSS"); Date date = new Date(); String str = sdf.format(date); System.out.println("格式化后的日期:" + str); } }
通过SimpleDateFormat类可以将一个Date型的数据变为String型的数据。
2、parse()-将String变回Date型
范例:parse()将String变回Date型
import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDateFormatDemo02 { public static void main(String[] args) throws Exception { String str = "2009-12-24 11:51:57.500"; // 准备好了一个要格式化的模板 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-ddHH:mm:ss.SSS"); Date date = sdf.parse(str); // 将String--> Date System.out.println("格式化后的日期:" + date); } }
依靠SimpleDateFormat可以完成String和Date型数据的转换。
3、不同类型的日期格式转换
实际上SimpleDateFormat类还可以完成日期格式的转换,例如:有两种不同类型的日期格式,可以通过此类转换:
import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDateFormatDemo03 { public static void main(String[] args) throws Exception { String oldDate = "2009-12-24 11:51:57.500"; String newDate = null; // 准备好了一个要格式化的模板 SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); SimpleDateFormat sdf2 = new SimpleDateFormat( "yyyy年MM月dd日HH时mm分ss秒SSS毫秒"); Date date = sdf1.parse(oldDate); // 从原日期字符串中取出日期数字 newDate = sdf2.format(date); // 新的日期格式 System.out.println("格式化后的日期:" + newDate); } }
八、Arrays类
Arrays类是一个数组的操作类,之前曾经使用过此类完成过排序的操作,但是此类还有填充及输出的功能。
import java.util.Arrays; public class ArraysDemo { public static void main(String[] args) { int temp[] = { 50, 45, 8, 9, 1, 23, 4, 5, 23, 21, 324 }; Arrays.sort(temp); System.out.println(Arrays.toString(temp)); Arrays.fill(temp, 1);// 将指定的int 值分配给指定int 型数组的每个元素。 System.out.println(Arrays.toString(temp)); } }
但是在这个类的sort()方法中有一个以下的排序操作:publicstatic void sort(Object[] a)
可以对一个对象数组进行排序,那么下面观察一下:
import java.util.Arrays; class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "姓名:" + this.name + ",年龄:" + this.age; } } public class SortObjectArray { public static void main(String[] args) { Person per[] = { new Person("张三", 20), new Person("李四", 19), new Person("王五", 23) }; Arrays.sort(per); for (int x = 0; x < per.length; x++) { System.out.println(per[x]); } } }
但是,此时执行的时候出现了以下的错误提示:
Exception in thread "main"java.lang.ClassCastException:Person cannot be cast to java.lang.Comparable |
此时提示的是一个类转换异常:Person类的对象不能向Comparable转换。
九、比较器
当需要对一组对象进行排序的时候,一定要指定比较规则,这种比较规则主要是将某一个类中的几个属性进行比较。
对于这种比较器的实现,在Java中有两种接口完成:Comparable:使用的最广泛的一种
Comparator:属于挽救的比较器
1、Comparable
Comparable接口主要是用于执行比较器操作的接口,定义如下:
public interface Comparable<T> { public int compareTo(T o); }
Comparable接口中只存在了一个compareTo()的方法,此方法的主要功能是编写比较规则的,此方法返回一个int型的数据,此值会返回三种结果:
· 0:两个对象相等
· 1:大于
· -1:小于
如果要使用Arrays.sort()进行排序的话,则肯定要在对象所在的类中进行编写比较器的操作。
import java.util.Arrays; class Person implements Comparable<Person> { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "姓名:" + this.name + ",年龄:" + this.age; } @Override public int compareTo(Person o) { if (this.age > o.age) { return 1; } else if (this.age < o.age) { return -1; } else { return 0; } } } public class SortObjectArray { public static void main(String[] args) { Person per[] = { new Person("张三", 20), new Person("李四", 19), new Person("王五", 23) }; Arrays.sort(per); for (int x = 0; x < per.length; x++) { System.out.println(per[x]); } } }
如果对象数组要排序,则对象所在的类必须实现Comparable接口。指定泛型
2、Comparable排序原理
Comparable排序的原理实际上就属于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 (this.data.compareTo(newNode.data) >= 0) { // 放在左子树 if (this.left == null) { this.left = newNode; } else { this.left.addNode(newNode); } } if (this.data.compareTo(newNode.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.println(this.data); if (this.right != null) { this.right.printNode(); } } } class BinaryTree { private Node root;// 根节点 public void add(Comparable data) { Node newNode = new Node(data); if (this.root == null) { this.root = newNode; } else { this.root.addNode(newNode); } } public void print() { if (this.root != null) { this.root.printNode(); } } } public class BinaryTreeDemo { public static void main(String[] args) { BinaryTree bt = new BinaryTree(); bt.add("B"); bt.add("B"); bt.add("A"); bt.add("C"); bt.print(); } }
3、Comparator
在Arrays类中可以使用此排序:public static <T> void sort(T[] a,Comparator<?super T> c)
此排序接收一个Comparator的接口实例。
public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "姓名:" + this.name + ",年龄:" + this.age; } }
但是,此类中由于没有使用Comparable接口,所以肯定是无法通过Arrays.sort()进行排序的。
所以,可以通过Comparator挽救一个排序的规则。
import java.util.Comparator; public class PersonComparator implements Comparator<Person> { @Override public int compare(Person o1, Person o2) { if (o1.getAge() > o2.getAge()) { return -1; } else if (o1.getAge() < o2.getAge()) { return 1; } else { return 0; } } }
所以,之后就可以继续使用Arrays类提供的sort()方法进行排序。
import java.util.Arrays; public class Demo { public static void main(String[] args) { Person per[] = { new Person("张三", 20), new Person("李四", 19), new Person("王五", 23) }; Arrays.sort(per, new PersonComparator()); for (int x = 0; x < per.length; x++) { System.out.println(per[x]); } } }
两种比较接口的区别:Comparable属于定义类的时候使用,而Comparator属于挽救的比较器,所在的包不同。
Comparable只有一个方法,而Comparator有两个方法。