java-API中的常用类,新特性之-泛型,高级For循环,可变参数

2023-05-25,,

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。

 import java.util.*;
class SystemDemo
{
public static void main(String[] args)
{ Properties prop = System.getProperties();
//Properties是HashTable的子类,是Map集合的子类对象;属性类,比较常用。
//该集合中存储的都是字符串,没有泛型定义。获取系统属性信息,与每台电脑的系统有关。
//可以通过map的方法取出该集合中的元素。
/*
//获取所有属性信息。
for(Object obj : prop.keySet())
{
String value = (String)prop.get(obj); System.out.println(obj+"::"+value);
}
*/ //如何在系统中自定义一些特有信息呢?
System.setProperty("mykey","myvalue"); //获取指定单个属性信息。
String value1 = System.getProperty("os.name"); System.out.println("os.name="+value1);
}
}

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");。

 class  RuntimeDemo
{
public static void main(String[] args) throws Exception
{
Runtime r = Runtime.getRuntime();
Process p = r.exec("D:\\Tencent\\QQ\\Bin\\QQProtect\\Bin\\QQProtect.exe"); Thread.sleep(4000);
p.destroy();
Process p1 = r.exec("notepad.exe RuntimeDemo.java" ); Thread.sleep(4000);
p1.destroy(); }
}

Date,Calendar类

 import java.util.*;
import java.text.*;
class DateDemo
{
public static void main(String[] args)
{
Date d = new Date();
System.out.println("time:"+d);//打印的时间看不懂,希望格式化时间。 //将模式封装到SimpleDateformat对象中。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 E hh:mm:ss"); //调用format方法让模式格式化指定Date对象。
String newtime = sdf.format(d);
System.out.println("newtime:"+newtime); //当前时间与协调世界时 1970 年 1 月 1 日午夜之间的时间差(以毫秒为单位测量)。
long l = System.currentTimeMillis();
System.out.println("currentTimeMillis="+l);
}
}
---------- java ----------
time:Sat Aug 10 22:48:04 CST 2013
newtime:2013年08月10日 星期六 10:48:04
currentTimeMillis=1376146084416 输出完成 (耗时 0 秒) - 正常终止
 import java.util.* ;
public class CalendarDemo{
public static void main(String args[]){
Calendar calendar = new GregorianCalendar(); // 实例化Calendar类对象 System.out.println("年: " + calendar.get(Calendar.YEAR));
System.out.println("月: " + (calendar.get(Calendar.MONTH) + 1));
System.out.println("日: " + calendar.get(Calendar.DAY_OF_MONTH));
System.out.println("时: " + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("分: " + calendar.get(Calendar.MINUTE));
System.out.println("秒: " + calendar.get(Calendar.SECOND));
System.out.println("毫秒: " + calendar.get(Calendar.MILLISECOND));
}
}
---------- java ----------
年: 2013
月: 8
日: 10
时: 23
分: 57
秒: 28
毫秒: 598 输出完成 (耗时 0 秒) - 正常终止

将指定字符串日期格式化

 import java.text.* ;
import java.util.* ;
public class SimpleDateFormatDemo{
public static void main(String args[]){
String strDate = "1988-10-19 10:11:30.345" ;
// 准备第一个模板,从字符串中提取出日期数字
String pat1 = "yyyy-MM-dd HH:mm:ss.SSS" ;
// 准备第二个模板,将提取后的日期数字变为指定的格式
String pat2 = "yyyy年MM月dd日 HH时mm分ss秒SSS毫秒" ;
SimpleDateFormat sdf1 = new SimpleDateFormat(pat1) ;// 实例化模板对象
SimpleDateFormat sdf2 = new SimpleDateFormat(pat2) ;// 实例化模板对象
Date d = null ;
try{
d = sdf1.parse(strDate) ; // 将给定的字符串中的日期提取出来 Date parse(String text, ParsePosition pos)解析字符串的文本,生成Date。 }catch(Exception e){ // 如果提供的字符串格式有错误,则进行异常处理
System.out.println("异常:日期格式错误!") ; // 打印异常信息
}
System.out.println(sdf2.format(d)) ; // 将日期变为新的格式
}
}
---------- java ----------
1988年10月19日 10时11分30秒345毫秒 输出完成 (耗时 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方法获得对应的随机数。

 import java.util.*;
class MathDemo
{
public static void main(String[] args)
{ Random r = new Random();
Set<Integer> ts = new HashSet<Integer>();
while(ts.size()!=7)
{
ts.add(r.nextInt(30)+1);//返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值(不包括)之间均匀分布的int值。
} Integer[] arr = ts.toArray(new Integer[ts.size()]);
System.out.println("30选7:"+Arrays.toString(arr)); show(); }
public static void show()
{
double d = Math.ceil(16.34);//ceil返回大于指定数据的最小整数。
double d1 = Math.floor(12.34);//floor返回小于指定数据的最大整数。 long l = Math.round(12.24);//四舍五入 double d2 = Math.pow(2,3);//2的3次幂
sop("d="+d);
sop("d1="+d1); sop("l="+l); sop("d2="+d2);
}
public static void sop(Object obj)
{ System.out.println(obj);
}
}
---------- java ----------
30选7:[4, 20, 23, 7, 24, 10, 26]
d=17.0
d1=12.0
l=12
d2=8.0 输出完成 (耗时 0 秒) - 正常终止

可变参数
JDK1.5后的新特性,通过一个可以变长度的数组来储存值并进行操作,本质上仍是数组,是各种数组的简写形式。使用时注意:可变参数一定要定义在参数列表最后面。
例如
public static void show(int... arr){}

静态导入
导入工具类中的静态成员,例如,import static java.util.Arrays.*;,导入Arrays类中所有静态成员。
某些方法是Object和工具类共同拥有的,必须说明具体调用者才能正确使用。例如,System.out.println(Arrays.toString(arr));不说明的话默认是Object调用。

可变参数和静态导入用一个例子说明

 import java.util.*;
import static java.util.Arrays.*;
class ParamMethodDemo
{
public static void main(String[] args)
{
/*
可变参数。
其实就是上一种数组参数的简写形式。
不用每一次都手动的建立数组对象。
只要将要操作的元素作为参数传递即可。
隐式将这些参数封装成了数组。
*/
show(2,3,4,5,6);
show(2,3,4,5,6,10,35,9);
show("abc","cca","xxc");
show("abc","cca","xxy","zza","yyw");
add(2,3,5);
}
public static void show(Integer... arr)
{
Arrays.sort(arr);//1,可以写成sort(arr);
System.out.println(Arrays.toString(arr));//toString()是Object类和工具类共同拥有的,必须说明具体调用者才能正确使用。
}
public static void show(String... arr)
{
sort(arr);//2,同1
System.out.println(Arrays.toString(arr));
}
public static void add(int x,int ...arr)//可变参数一定要定义在参数列表最后面
{
int sum=x;
for(int i=0;i<arr.length;i++)
{
sum+=arr[i];
}
System.out.println("sum="+sum);
}
}
---------- java ----------
[2, 3, 4, 5, 6]
[2, 3, 4, 5, 6, 9, 10, 35]
[abc, cca, xxc]
[abc, cca, xxy, yyw, zza]
sum=10 输出完成 (耗时 0 秒) - 正常终止

 高级for循环
1.5以后,将iterator()方法单独构成一个接口Iterable,方便以后新建集合的使用,并提供高级for循环。底层仍然是调用迭代器,简化了书写。各种数据类型皆可,引用型和基本型
    格式:
    for(数据类型 变量名 : 被遍历的集合(Collection)或者数组)
    {
    
    }
    遍历中的操作
    高级for循环:对集合进行遍历,只能获取集合中的元素、但不能对集合进行操作,使用有局限性。
    迭代器:除了遍历,还可以remove()集合中的元素;如果使用ListIterator迭代器,还可以在遍历过程中对集合进行增删改查的动作。

高级for循环内部使用的数据类型是集合的泛型,如果集合没有定义泛型,使用Object。因为1.5以后定义了泛型,所以数据类型是泛型。

 /*
高级for循环
应用在Map取出元素
*/ import java.util.*;
class ForEachDemo
{
public static void main(String[] args)
{ HashMap<Integer,String> hm = new HashMap<Integer,String>();
hm.put(1,"a");
hm.put(2,"b");
hm.put(3,"c"); //第一种方法 for(Map.Entry<Integer,String> me : hm.entrySet())
{
System.out.println(me.getKey()+"....."+me.getValue());
} //第二种方法 Set<Integer> keyset = hm.keySet(); for(Integer i : hm.keySet())//set里什么类型for里就是什么类型
{
System.out.println(i+"-----"+hm.get(i));
}
}
}
---------- java ----------
1.....a
2.....b
3.....c
1-----a
2-----b
3-----c 输出完成 (耗时 0 秒) - 正常终止

泛型

JDK1.5版本以后出现新特性。用于解决安全问题,是一个类型安全机制。

好处:
1.将运行时期出现问题ClassCastException,转移到了编译时期。
2.提高了程序的安全性。
3.泛型类的出现优化了程序设计。
4.避免了类型强制转换的麻烦。

弊端:使用泛型可以接受不同的对象,但是对象的特有方法不能再使用。

泛型格式:通过<>来定义要操作的引用数据类型。
在使用java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见,只要查API见到<>就要定义泛型。其实<> 就是用来接收类型的。当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

什么时候定义泛型类?
当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展,现在定义泛型来完成扩展。


型类定义的泛型,在整个类中有效。如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。为了让不同方法可以操作不同
类型,而且类型还不确定,那么可以将泛型定义在方法上。特殊之处:静态方法不可以访问类上定义的泛型。如果静态方法操作的应用数据类型不确定,可以将泛型
定义在方法上。

注意:泛型的位置:返回值类型的前面,修饰符的后面。泛型类的位置:类名后面。

泛型定义在类和方法上

 class Demo<T>
{
public void show(T t)
{
System.out.println("show:"+t);
}
public <Q> void print(Q q)
{
System.out.println("print:"+q);
}
public static <W> void method(W t)//静态方法不可以访问类上定义的泛型。如果静态方法操作的应用数据类型不确定,要将泛型定义在静态方法上。
{
System.out.println("method:"+t);
}
}
class GenericDemo
{
public static void main(String[] args)
{
Demo <String> d = new Demo<String>();
d.show("haha");
//d.show(4);编译时不通过,泛型随对象。已经被指定为操作String
d.print(5);
d.print("hehe");//泛型方法可以操作不同数据类型 Demo.method("hahahahha");
}
}

 泛型定义在接口上

 interface Inter<T>
{
void show(T t);
}
//子类已经确定操作类型
class Demo_1 implements Inter<String>
{
public void show(String s)
{
System.out.println("show = "+s);
}
public<E> void print(E e)//依然可以有其他类型
{
System.out.println("print = "+e);
}
}
//子类也不确定操作类型
class Demo_2<T> implements Inter<T>
{
public void show(T t)
{
System.out.println("show = "+t);
}
public<E> void print(E e)
{
System.out.println("print = "+e);
}
}

泛型的高级应用

当操作类型不明确时,可以使用通配符(站位符?)来表示。例如,

 public static void printArray(ArrayList<?> ar)
{
Iterator<?> it = ar.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}

泛型的限定;
? extends E: 可以接收E类型或者E的子类型。上限。
? super E: 可以接收E类型或者E的父类型。下限。
Comparator比较器可以传入父类<? super E>,使得子类也可以使用比较器。但比较方法必须是父类的。多态原理。

java-API中的常用类,新特性之-泛型,高级For循环,可变参数的相关教程结束。

《java-API中的常用类,新特性之-泛型,高级For循环,可变参数.doc》

下载本文的Word格式文档,以方便收藏与打印。