API中的常用类
System类
System类包含一些有用的类字段和方法。它不能被实例化。属性和方法都是静态的。
out,标准输出,默认打印在控制台上。通过和PrintStream打印流中的方法组合构成输出语句。
In,标准输入,默认是键盘,获取键盘录入的所有内容。
描述系统的一些信息:
Properties getProperties(),获得系统的属性信息。
Properties是HashTable的子类,是Map集合的子类对象;属性类,比较常用。该集合中存储的都是字符串,没有泛型定义。获取系统属性信息,与每台电脑的系统有关。
java是跨平台语言,需要知道系统种类决定以后的操作。
开发中,需要先了解平台的系统信息,进而决定采用何种操作。
设置信息:setProperty,在系统中自定义一些特有信息,例如,配置文件、目录等。
获得单个信息:getProperty(String key),获取指定属性的信息,例如,os.name。指定键没有的话,返回null。
虚拟机动态的加载指定系统信息:在DOS通过-D设置信息,然后再运行,例如,java –Dhaha=qq SystemDemo。
1 import java.util.*; 2 class SystemDemo 3 { 4 public static void main(String[] args) 5 { 6 7 Properties prop = System.getProperties(); 8 //Properties是HashTable的子类,是Map集合的子类对象;属性类,比较常用。 9 //该集合中存储的都是字符串,没有泛型定义。获取系统属性信息,与每台电脑的系统有关。 10 //可以通过map的方法取出该集合中的元素。 11 /* 12 //获取所有属性信息。 13 for(Object obj : prop.keySet()) 14 { 15 String value = (String)prop.get(obj); 16 17 System.out.println(obj+"::"+value); 18 } 19 */ 20 21 //如何在系统中自定义一些特有信息呢? 22 System.setProperty("mykey","myvalue"); 23 24 25 //获取指定单个属性信息。 26 String value1 = System.getProperty("os.name"); 27 28 System.out.println("os.name="+value1); 29 } 30 }
Runtime类
Runtime没有构造函数、多是非静态方法,只提供一个静态方法获取本类对象,进而调用各个方法。该静态方法是,getRuntime(),返回值类型是本类类型。
由这个特点可以看出该类使用了单例设计模式完成。
exec(String command),在单独的进程中执行指定的字符串命令。字符串命令可能会出现错误,所以需要抛出异常。
例如,run.exec("D:\\Tencent\\QQ\\Bin\\QQProtect\\Bin\\QQProtect.exe");启动QQ。
exec()返回一个进程,Process类,抽象类,没有构造函数,因为底层在系统内创建进程对象。内部的destroy()方法,秒杀子进程。只能杀死自己启动的对象,已经启动的对象无法杀死。
还可以通过程序打开文件,例如,run.exec("notepad.exe RuntimeDemo.java");。
1 class RuntimeDemo 2 { 3 public static void main(String[] args) throws Exception 4 { 5 Runtime r = Runtime.getRuntime(); 6 Process p = r.exec("D:\\Tencent\\QQ\\Bin\\QQProtect\\Bin\\QQProtect.exe"); 7 8 Thread.sleep(4000); 9 p.destroy(); 10 Process p1 = r.exec("notepad.exe RuntimeDemo.java" ); 11 12 Thread.sleep(4000); 13 p1.destroy(); 14 15 } 16 }
Date,Calendar类
1 import java.util.*; 2 import java.text.*; 3 class DateDemo 4 { 5 public static void main(String[] args) 6 { 7 Date d = new Date(); 8 System.out.println("time:"+d);//打印的时间看不懂,希望格式化时间。 9 10 //将模式封装到SimpleDateformat对象中。 11 SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 E hh:mm:ss"); 12 13 //调用format方法让模式格式化指定Date对象。 14 String newtime = sdf.format(d); 15 System.out.println("newtime:"+newtime); 16 17 //当前时间与协调世界时 1970 年 1 月 1 日午夜之间的时间差(以毫秒为单位测量)。 18 long l = System.currentTimeMillis(); 19 System.out.println("currentTimeMillis="+l); 20 } 21 } 22 ---------- java ---------- 23 time:Sat Aug 10 22:48:04 CST 2013 24 newtime:2013年08月10日 星期六 10:48:04 25 currentTimeMillis=1376146084416 26 27 输出完成 (耗时 0 秒) - 正常终止
1 import java.util.* ; 2 public class CalendarDemo{ 3 public static void main(String args[]){ 4 Calendar calendar = new GregorianCalendar(); // 实例化Calendar类对象 5 6 System.out.println("年: " + calendar.get(Calendar.YEAR)); 7 System.out.println("月: " + (calendar.get(Calendar.MONTH) + 1)); 8 System.out.println("日: " + calendar.get(Calendar.DAY_OF_MONTH)); 9 System.out.println("时: " + calendar.get(Calendar.HOUR_OF_DAY)); 10 System.out.println("分: " + calendar.get(Calendar.MINUTE)); 11 System.out.println("秒: " + calendar.get(Calendar.SECOND)); 12 System.out.println("毫秒: " + calendar.get(Calendar.MILLISECOND)); 13 } 14 } 15 ---------- java ---------- 16 年: 2013 17 月: 8 18 日: 10 19 时: 23 20 分: 57 21 秒: 28 22 毫秒: 598 23 24 输出完成 (耗时 0 秒) - 正常终止
将指定字符串日期格式化
1 import java.text.* ; 2 import java.util.* ; 3 public class SimpleDateFormatDemo{ 4 public static void main(String args[]){ 5 String strDate = "1988-10-19 10:11:30.345" ; 6 // 准备第一个模板,从字符串中提取出日期数字 7 String pat1 = "yyyy-MM-dd HH:mm:ss.SSS" ; 8 // 准备第二个模板,将提取后的日期数字变为指定的格式 9 String pat2 = "yyyy年MM月dd日 HH时mm分ss秒SSS毫秒" ; 10 SimpleDateFormat sdf1 = new SimpleDateFormat(pat1) ;// 实例化模板对象 11 SimpleDateFormat sdf2 = new SimpleDateFormat(pat2) ;// 实例化模板对象 12 Date d = null ; 13 try{ 14 d = sdf1.parse(strDate) ; // 将给定的字符串中的日期提取出来 Date parse(String text, ParsePosition pos)解析字符串的文本,生成Date。 15 16 }catch(Exception e){ // 如果提供的字符串格式有错误,则进行异常处理 17 System.out.println("异常:日期格式错误!") ; // 打印异常信息 18 } 19 System.out.println(sdf2.format(d)) ; // 将日期变为新的格式 20 } 21 } 22 ---------- java ---------- 23 1988年10月19日 10时11分30秒345毫秒 24 25 输出完成 (耗时 0 秒) - 正常终止
Math和Random类
各种数据的计算方法,都是静态方法。
ceil()返回大于或等于指定数据的最小整数。
floor()返回小于或等于指定数据的最大整数。
round():四舍五入,返回值尽量是long。
pow(a,b):a的b次幂,返回值尽量是double型。
randow():随机数,返回带正号的double值,大于或等于 0.0,小于 1.0。通过运算,可以获得其他区间的随机数,例如,int d = (int)(Math.random()*10+1);
也可以调用Random类中的方法,更广泛的获取随机数。创建随机数生成器,在通过各种next方法获得对应的随机数。
1 import java.util.*; 2 class MathDemo 3 { 4 public static void main(String[] args) 5 { 6 7 8 Random r = new Random(); 9 Set<Integer> ts = new HashSet<Integer>(); 10 while(ts.size()!=7) 11 { 12 ts.add(r.nextInt(30)+1);//返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的int值。 13 } 14 15 Integer[] arr = ts.toArray(new Integer[ts.size()]); 16 System.out.println("30选7:"+Arrays.toString(arr)); 17 18 show(); 19 20 } 21 public static void show() 22 { 23 double d = Math.ceil(16.34);//ceil返回大于指定数据的最小整数。 24 double d1 = Math.floor(12.34);//floor返回小于指定数据的最大整数。 25 26 long l = Math.round(12.24);//四舍五入 27 28 double d2 = Math.pow(2,3);//2的3次幂 29 sop("d="+d); 30 sop("d1="+d1); 31 32 sop("l="+l); 33 34 sop("d2="+d2); 35 } 36 public static void sop(Object obj) 37 { 38 39 System.out.println(obj); 40 } 41 } 42 ---------- java ---------- 43 30选7:[4, 20, 23, 7, 24, 10, 26] 44 d=17.0 45 d1=12.0 46 l=12 47 d2=8.0 48 49 输出完成 (耗时 0 秒) - 正常终止
可变参数
JDK1.5后的新特性,通过一个可以变长度的数组来储存值并进行操作,本质上仍是数组,是各种数组的简写形式。使用时注意:可变参数一定要定义在参数列表最后面。
例如
public static void show(int... arr){}
静态导入
导入工具类中的静态成员,例如,import static java.util.Arrays.*;,导入Arrays类中所有静态成员。
某些方法是Object和工具类共同拥有的,必须说明具体调用者才能正确使用。例如,System.out.println(Arrays.toString(arr));不说明的话默认是Object调用。
可变参数和静态导入用一个例子说明
1 import java.util.*; 2 import static java.util.Arrays.*; 3 class ParamMethodDemo 4 { 5 public static void main(String[] args) 6 { 7 /* 8 可变参数。 9 其实就是上一种数组参数的简写形式。 10 不用每一次都手动的建立数组对象。 11 只要将要操作的元素作为参数传递即可。 12 隐式将这些参数封装成了数组。 13 */ 14 show(2,3,4,5,6); 15 show(2,3,4,5,6,10,35,9); 16 show("abc","cca","xxc"); 17 show("abc","cca","xxy","zza","yyw"); 18 add(2,3,5); 19 } 20 public static void show(Integer... arr) 21 { 22 Arrays.sort(arr);//1,可以写成sort(arr); 23 System.out.println(Arrays.toString(arr));//toString()是Object类和工具类共同拥有的,必须说明具体调用者才能正确使用。 24 } 25 public static void show(String... arr) 26 { 27 sort(arr);//2,同1 28 System.out.println(Arrays.toString(arr)); 29 } 30 public static void add(int x,int ...arr)//可变参数一定要定义在参数列表最后面 31 { 32 int sum=x; 33 for(int i=0;i<arr.length;i++) 34 { 35 sum+=arr[i]; 36 } 37 System.out.println("sum="+sum); 38 } 39 } 40 ---------- java ---------- 41 [2, 3, 4, 5, 6] 42 [2, 3, 4, 5, 6, 9, 10, 35] 43 [abc, cca, xxc] 44 [abc, cca, xxy, yyw, zza] 45 sum=10 46 47 输出完成 (耗时 0 秒) - 正常终止
高级for循环
1.5以后,将iterator()方法单独构成一个接口Iterable,方便以后新建集合的使用,并提供高级for循环。底层仍然是调用迭代器,简化了书写。各种数据类型皆可,引用型和基本型
格式:
for(数据类型 变量名 : 被遍历的集合(Collection)或者数组)
{
}
遍历中的操作
高级for循环:对集合进行遍历,只能获取集合中的元素、但不能对集合进行操作,使用有局限性。
迭代器:除了遍历,还可以remove()集合中的元素;如果使用ListIterator迭代器,还可以在遍历过程中对集合进行增删改查的动作。
高级for循环内部使用的数据类型是集合的泛型,如果集合没有定义泛型,使用Object。因为1.5以后定义了泛型,所以数据类型是泛型。
1 /* 2 高级for循环 3 应用在Map取出元素 4 */ 5 6 import java.util.*; 7 class ForEachDemo 8 { 9 public static void main(String[] args) 10 { 11 12 HashMap<Integer,String> hm = new HashMap<Integer,String>(); 13 hm.put(1,"a"); 14 hm.put(2,"b"); 15 hm.put(3,"c"); 16 17 //第一种方法 18 19 for(Map.Entry<Integer,String> me : hm.entrySet()) 20 { 21 System.out.println(me.getKey()+"....."+me.getValue()); 22 } 23 24 //第二种方法 25 26 Set<Integer> keyset = hm.keySet(); 27 28 for(Integer i : hm.keySet())//set里什么类型for里就是什么类型 29 { 30 System.out.println(i+"-----"+hm.get(i)); 31 } 32 } 33 } 34 ---------- java ---------- 35 1.....a 36 2.....b 37 3.....c 38 1-----a 39 2-----b 40 3-----c 41 42 输出完成 (耗时 0 秒) - 正常终止
泛型
JDK1.5版本以后出现新特性。用于解决安全问题,是一个类型安全机制。
好处:
1.将运行时期出现问题ClassCastException,转移到了编译时期。
2.提高了程序的安全性。
3.泛型类的出现优化了程序设计。
4.避免了类型强制转换的麻烦。
弊端:使用泛型可以接受不同的对象,但是对象的特有方法不能再使用。
泛型格式:通过<>来定义要操作的引用数据类型。
在使用java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见,只要查API见到<>就要定义泛型。其实<> 就是用来接收类型的。当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。
什么时候定义泛型类?
当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展,现在定义泛型来完成扩展。
泛 型类定义的泛型,在整个类中有效。如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。为了让不同方法可以操作不同 类型,而且类型还不确定,那么可以将泛型定义在方法上。特殊之处:静态方法不可以访问类上定义的泛型。如果静态方法操作的应用数据类型不确定,可以将泛型 定义在方法上。
注意:泛型的位置:返回值类型的前面,修饰符的后面。泛型类的位置:类名后面。
泛型定义在类和方法上
1 class Demo<T> 2 { 3 public void show(T t) 4 { 5 System.out.println("show:"+t); 6 } 7 public <Q> void print(Q q) 8 { 9 System.out.println("print:"+q); 10 } 11 public static <W> void method(W t)//静态方法不可以访问类上定义的泛型。如果静态方法操作的应用数据类型不确定,要将泛型定义在静态方法上。 12 { 13 System.out.println("method:"+t); 14 } 15 } 16 class GenericDemo 17 { 18 public static void main(String[] args) 19 { 20 Demo <String> d = new Demo<String>(); 21 d.show("haha"); 22 //d.show(4);编译时不通过,泛型随对象。已经被指定为操作String 23 d.print(5); 24 d.print("hehe");//泛型方法可以操作不同数据类型 25 26 Demo.method("hahahahha"); 27 } 28 }
泛型定义在接口上
1 interface Inter<T> 2 { 3 void show(T t); 4 } 5 //子类已经确定操作类型 6 class Demo_1 implements Inter<String> 7 { 8 public void show(String s) 9 { 10 System.out.println("show = "+s); 11 } 12 public<E> void print(E e)//依然可以有其他类型 13 { 14 System.out.println("print = "+e); 15 } 16 } 17 //子类也不确定操作类型 18 class Demo_2<T> implements Inter<T> 19 { 20 public void show(T t) 21 { 22 System.out.println("show = "+t); 23 } 24 public<E> void print(E e) 25 { 26 System.out.println("print = "+e); 27 } 28 }
泛型的高级应用
当操作类型不明确时,可以使用通配符(站位符?)来表示。例如,
1 public static void printArray(ArrayList<?> ar) 2 { 3 Iterator<?> it = ar.iterator(); 4 while(it.hasNext()) 5 6 { 7 System.out.println(it.next()); 8 } 9 }
泛型的限定;
? extends E: 可以接收E类型或者E的子类型。上限。
? super E: 可以接收E类型或者E的父类型。下限。
Comparator比较器可以传入父类<? super E>,使得子类也可以使用比较器。但比较方法必须是父类的。多态原理。