常用API
API
由Java提供, 现成的程序组件(类)。API封装了开发时候常用的功能!应多查API 的手册.
String类
String str = "String";//通过字面量直接在常量池进行创建
String h = new String("hello");//通过构造动态创建字符串hello
注意点:
- 字符串对象不可改变,底层封装了字符数组,任何的操作都不能改变这个字符数组,好处是字符串可以像基本类型一样使用(进行重用,节省资源/内存)!字符串推荐使用字面量形式创建
- 字面量存储在常量池可供重复使用
- String类常用来查看字符串的一些属性或正则匹配拆分等操作,若要经常改变字符串,建议使用StringBuilder动态字符串类,用于字符串的增删查取操作
- 常量池的任何字符改变和新建的操作都会建立新常量字符串地址,特别注意是否返回给原字符串。每new一个字符串,都会建立新地址如果之前没创建过该字符串,同时会创建常量池对象,公用底层的char数组.字符串变量内容改变一定创建新对象.
- 字面量 或 常量的连接结果, 会重用字符串常量池中的对象.
- 字符串变量的连接结果不会常量池优化(即使常量池里有 ,也不能直接引用),需要新建一个对象来引用.
- 字符串当遇到字面量与变量进行内容比较时应当使用:字面量.equals(变量),因为变量在实际开发中不能保证null,所以可能引发空指针异常.字面量一定不是空所以不会出现该问题.
- String是final类型的,不能被继承
String类的常用API
//静态方法:
String numString = String.valueOf(123.456);//支持各种参数重载,转为字符串类型
//实例方法:
String upper = str.toUpperCase();//英文全大写
String lower = str.toLowerCase();//英文全小写
String trim = "/n /r hello world /t ".trim(); //去除两端看不见的空白字符
//字符串for循环遍历:
for(int i=0;i<str.length();i++){//除了数据库 所有的下标、索引都以0开始
char c = str.charAt(i); //逐次取出字符,从而进行遍历
System.out.println(c);
}
int n = str.indexOf("t");//字符/子字符串查找,返回第一次出现的索引 未找到则返回-1
int m = str.indexOf("t",3);//从索引3(包含3)的位置进行查找
int x = str.lastIndexOf("tr",3);//从最后开始查找"tr",查到索引为3开始,若查找到的话,返回"t"对应的索引,没找到则返回-1
boolean b = str.startsWith("S",3);//判断前缀,从下标3开始判断
boolean e = str.endsWith("g");//判断后缀
String subStr = str.substring(1,1+2);// 含头不含尾 tr
String subStr2 = str.substring(1);//从索引为1开始截取
boolean tt = str.equalsIgnoreCase(subStr);//忽略大小比较字符串内容是否相同
boolen tf = str.maches("[0-9A-Za-z_]+"); //测试是否匹配正则表达式 java里的省略掉了边界符^$ 但依然是全匹配
String[] strs = str.splite("\\."); //按正则表达式进行拆分
String newStr = str.replaceAll("(s|g)","#"); //按照正则查找并进行全局替换
正则表达式
用于声明字符串的规则表达式。==经常用于检测一个字符串是否符合特定规则
语法:
字符集合:
[abcd] abcd四个字符选一个
[a-f] a到f字符选一个
[^abcd] 除了abcd字符的其他字符
缩写版
. 任意字符
\d 数字
\D 非数字
\w 单词字符(含_)
\W 非单词字符
\s 空白
\S 非空白
数量词
X{n} n个X
X{n,m} n到m个
X{n, } 最少n个
\? {0,1}
\* {0,}
\+ {1,}
\^开始
\$结束
分组
(序列1|序列2) 表示满足序列1或者满足序列2
常见案例:
邮政编码的规则 \d{6}
身份证的规则 d{17}[\dXx]
用户名的规则: 8到11个单词字符 \w{8,11}
检查一个文件是否为jpeg照片文件: .+\.jpe?g
检查一个文件是否为照片文件: .+\.(jpe?g|png|gif)
Excel能够支持的文件名规则 : .+\.xls[xbm]?
手机号的规则: (0086|\+86)?\s*1\d{10}
其它
- String的实例方法compareTo():默认按字典顺序对字符串进行比较
StringBuffer类(线程安全)/StringBuilder类(非线程安全)
注意点:
- 两个类API用法完全相同
- 动态字符串类,解决了字符串频繁修改内容导致的资源消耗的问题
- 内部是一个可变的字符数组,所以所有的字符串内容修改都是在这个对象内完成的 ,而不会因为每次的内容修改创建新的对象
- StringBuilder提供了编辑字符串操作的相关方法(增,删,改,插入),java 提供的用于计算字符串的API, 其运算性能比较快.
- String覆盖了equals方法和hashCode方法,而StringBuffer没有覆盖equals方法和hashCode方法,将StringBuffer对象存储进Java集合类中时可能会出现问题。
StringBuilder类的常用API
StringBuilder sb = new StringBuilder("这里放字符串类型"); //不能直接给字面量
int cap = sb.capacity(); //容量
int num = sb.length(); //实际字符个数
String st = sb.append("末尾追加").insert(1,"从1插入").replace(3,3+4,"替换").delete(0,9).reverse().toString(); //函数式编程风格
其它
Object类
注意点:
- java.lang.Object类位于顶端,所有类的*父类
- 无extends显式继承的类都默认自动继承Object类,定义类的时候,类中建议重写Object类中的toString(),equals(),hashCode()方法,不是必须重写,但最好按业务需求重写
- Object的toString方法,该方法默认会返回一个“以文本方式表示”此对象的字符串的形式:包名.类@ hashCode值。这个默认方法是没有实际意义的结果,所以需要重写toString方法以返回更有意义的信息。
- 重写equals的目的是定义当前对象与给定的参数对象比较内容是否相同.这里也没有严格要求必须两个对象所有属性都必须完全相同,可以根据实际开发情况而定.
Object类的常用API
Object obj = new Object();
Class cls = obj.getClass();//得到类
int hashcode = obj.hashcode();
boolean b = obj.equals(other);
String str = obj.toString();//println(object)自动调用toString();
obj.wait();
obj.notify();
obj.notifyAll();
其它
包装类(以Integer为例)
注意点:
- 当"=="两边都是包装类时,比较的是地址;但如果任一边出现了表达式(包括算术表达式 )则会自动拆箱为基本类型进行数值比较;包装类和基本类型比较值时自动转化为基本类型;
- 数字类型的包装类都支持两个常量:MAX_VALUE,MIN_VALUE分别表示对应的基本类型的取值范围
- 包装类用于将基本类型包装为对象
- 包装类型计算性能没有基本类型好,要尽量避免大量使用包装类进行计算。
- java5开始 自动拆装箱,需注意自动拆装箱容易引发空指针异常!
Integer类的常用API
//静态方法
Integer i = Integer.valueof(128);
//实例方法
int d = i.intvalue();//拆包
int max = Integer.MAX_VALUE;
int min = Integer.MIN_VALUE;
int in = Integer.parseInt("123");//字符串转数字
其它
##File类
注意点:
- File的每一个实例是用于表示硬盘上的一个文件或目录,但是不能访问文件数据.
- 在eclipse中运行程序时,"当前目录"指定位该类所处的项目目录.
- 在表示文件或目录时指定的路径尽量不要使用 绝对路径,因为不同的操作系统路径格式不一致.
- 抽象路径应尽量使用相对路径,并且目录的层级分隔符不要直接写”/”或”\”,可以使用File.separator这个常量表示,以避免不同系统带来的差异。但写"/"也能通用在各种系统
- File对象所表示的是一个目录时,在删除时默认需要保证此为空目录才可以成功删除(目录中不能含有任何子项)。删除以后磁盘文件就不存在了,但是内存对象还在
File类的常用API
File file = new File("./demo.txt");//.为当前目录 创建内存文件对象,并不是创建文件或者文件夹,甚至并不一定有对应的磁盘文件
File file2 = new File(".","demo2.txt");
boolean b = file.createNewFile();//根据文件对象创建真实文件 如果没有写入权限,则出现异常!!
String name = file.getName();
Long length = file.length();//表示该文件所占用的字节量
boolean b1 = file.canRead();
boolean b2 = file.canWrite();
boolean b3 = file.isHidden();
boolean b4 = file.isexists();
long time = file.lastModified();//最后修改时间 ms值
boolean b5 = file.mkdir();//创建目录
boolean b6 = file.mkdirs();//多级目录 此操作失败时也可能已经成功地创建了一部分必需的父目录
boolean b7 = file.delete();//当且仅当成功删除文件或目录时,返回 true;否则返回 false。
boolean b8 = file.isFile();
boolean b9 = file.isDirectory();
File[] subs = file.listFiles();//如果抽象路径名不表示一个目录,或者发生 I/O 错误,则返回 null。
boolean b10 = file.renameTo(file2);//把file的名字改为file2,改完之后file就不存在了
//文件过滤器:
File[] subs1 = file.listFiles(
new FileFilter(){
public boolean accept(File file){
return file.getName().StartsWith("."); //选择文件名以点开始的文件
}
}
);
文件分隔符
- Windows 的文件分隔符 :\
- Linux 的文件分隔符 :/
- File 类提供了自动适应操作系统的文件分隔符:变量File.separator或随着操作系统自动变化,可以利用这变量,编写跨系统的程序:“demo”+File.separator+“test.txt”
其它
RandomAccessFile类
注意点
- 该类是专门用来读写文件数据的,其基于指针进行读写数据的,即:RAF总是在指针当前位置读或写字节的,并且读写完毕后指针会自动移动到下一个字节的位置.
2.内存中的字符串是char数据,不是byte类型,不能直接IO,需要先进行编码,编码为byte数据在进行读写。文字信息必须经过编码才能写到文件中。读取文件时候需要进行解码处理。 如果编码和解码的规则不一致就会出现乱码问题!!
3.常见字符集:GBK:国标编码 中文2字节 ;UTF-8:unicode的子集,也成为万国码 中文3字节 英文或符号占1个字节;ISO8859-1:欧洲字符集,不支持中文
RodomAccessFile类API
RodomAccessFile raf = new RodomAccessFile("./1.txt","r");
RodomAccessFile raf2 = new RodomAccessFile(file,"rw");
raf.write(255);//只能写int的最低8位 大于255的高位全部舍弃
int d = raf.read();//返回读取的那一个字节 若返回-1说明读到文件末尾
raf.seek(0); //操作文件指针,返回文件最开始
long pos = raf.getFilePointer();//获得文件指针当前位置 0表在文件开头
raf.writeInt(257); //写1个int(4位) 可理,可写其他基本类型
int d2 = raf.readInt();
//块读写
byte[] buf = new byte[1024*8]();
int len = raf.read(buf); //返回读入缓冲区实际的字节长度,若-1则说明是文件末尾
raf.write(buf);
raf.write(buf,0,len);//将给定数组的下标为0的len长度写入文件中
raf.close();
//字符集格式转换
byte[] data = str.getBytes("gbk");//字符集编码
String str = new String(data,0,len."utf-8");//字符集解码
其它
文件流 类
注意点
- java.io.InputStream:所有字节输入流的父类,是一个抽象类,规定了所有字节输入流都必须具备的读取字节的方法
- java.io.OutputStream:所有字节输出流的父类,是一个抽象类,规定了所有字节输出流都必须具备的写出字节的方法
- 通过缓冲输出流写出的字节并不会立刻被写入文件,会先存入其内部数组,直到给数组满了才会一次性写出所有数据。这样做等同于提高写出数据量减少写出次数提高写出效率。
- 缓冲流实际上本质就是进行块读写操作,无论我们使用缓冲流进行何种读写方式(单字节读写,块读写,最终都会被缓冲流转换为块读写形式通过文件流进行实际操作.缓冲流内部维护了一个8k的字节数组,用于块读写操作.
- 对象是存在于内存中的,实例类希望能被对象流读写,那么要求当前类必须实现java.io.Serializable接口实现,该接口不需要重写任何方法。其只是作为可序列化的标志。必须遵守实现序列化接口是添加序列化序列化 版本号,可以保证对象序列化、反序列化的稳定。减少更改类对序列化的影响。对象经序列化和反序列化后不是同一个对象.
- RAF和各种文件流在使用后均需关闭,多层嵌套的文件流关最外层即可.
- java.io.Reader和java.io.Writer是字符流的父类,字符流只是方便我们读写字符,底层本质还是读写字节,只是字节与字符的转换工作交给了字符流来完成.
常用API
//节点流
FileOutputStream fos = new FileOutputStream("1.txt",true);//有true为追加模式,没有为覆盖模式
byte[] data = new byte[]();
fos.write(data);
FileInputStream fis = new FileInputStream();
int len = fis.read(data);
String str = new String(data,0,len,"utf-8");
fis.close();
fos.close();
//缓冲字节流:高级流
BufferedOutputStream bos = new BufferedOutputStream(fos);
bos.flush();//强制将当前缓冲区的数据写出
bos.close();//会自动调用flush();
BufferedInputStream bis = new BufferedInputStream(fis);
//对象流:对java中的对象进行读写
ObjectOutputStream oos = new ObjectOutputStream(fos); //序列化
oos.writeObject(new Person());
ObjectInputStream ois = new ObjectInputStream(fis); //反序列化
Person p = (Person) ois.readObject();//强转
//转换流
OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
IntputStreamReader isr = new IntputStreamReader(fis,"UFT-8");
osw.write("hello");
//缓冲字符流
BufferedReader br = new BufferedReader(isr);
br.readline();//读一行 返回的字符串中不含有最后读取到的换行符.若返回值为null,则表示末尾
//打印输出流
PrintWriter pw = new PrintWriter("1.txt","UTF-8");
PrintWriter pw2 = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("2.txt",true),"utf-8"
)
),true //配合println自动行刷新
)
pw.close();
其它
异常(exception)类
注意点
- 当JVM运行程序是发现出现了某个异常时会自动实例化该类型的异常实例,并将代码执行过程设置到该异常实例中将其抛出.若抛出异常的代码没有被异常处理机制包含,那么JVM会将该异常抛到当前方法之外,若抛出到main方法之外,则当前程序中断. (单线程情况下)
- 多个catch语句中若存在父子类,则应把子类异常写前面,父类异常写后面
- 应当养成一个好习惯,在最后一个catch捕获Exception,防止因为捕获到意料之外的异常导致程序中断
4.finally语句为异常处理提供一个统一的出口,使得在控制流程转到程序其它部分以前,能够对程序的状态作统一管理。finally块只能定义在异常处理机制的最后,可以直接跟在try后面或者最后一个catch之后, finally可以保证只要程序运行到try当中,那么无论try当中的代码片段是否出现异常,finally块里面的代码都必然执行.通常把释放资源等操作放在finally中,比如流的关闭.删除临时文件
5.throw关键字,用于将一个异常抛出.通常两种情况会主动抛出一个异常:
程序遇到一个满足语法要求,但是不满足业务逻辑要求的时候可以主动抛出一个异常给调用者;
程序出现了异常,但是不应当在当前代码片段中解决该异常时可以抛出给调用者. - 一个方法内部使用throw抛出一个异常,就要在方法上使用throws声明该异常的抛出以告知调用这处理这个异常.只有RuntimeException及其子类型异常在方法中抛出是不要求必须在方法上声明该异常的抛出,其他类型异常则是必须的,否则编译不通过.
- 异常是定义了程序中遇到的可恢复的错误,而不是编译时的语法错误.
任何方法都可以抛出异常(包括main方法) - 在java出现之前,大多使用返回值来标识程序出现的异常情况,但有着一些缺点:
这些返回值本身并不能解释该返回值是否代表一个异常情况发生了和该异常的具体情况,
需要调用API的程序自己判断并解释返回值的含义。其次,并没有一种机制来保证异常情况一定会得到处理,调用程序可以简单的忽略该返回值,需要调用API的程序员记住去检测返回值并处理异常情况。这种方式还让程序代码变得冗长,尤其是当进行IO操作等容易出现异常情况的处理时,代码的很大部分用于处理异常情况的switch分支,程序代码的可读性变得很差。
9.异常处理机制:
当程序中抛出一个异常后,程序从程序中导致异常的代码处跳出,java虚拟机检测寻找和try关键字匹配的处理该异常的catch块,
如果找到,将控制权交到catch块中的代码,然后继续往下执行程序,try块中发生异常的代码不会被继续执行。
如果没有找到处理该异常的catch块,在所有的finally块代码被执行和当前线程的所属的ThreadGroup的uncaughtException方法被调用后,
遇到异常的当前线程被中止。 - 所有异常都继承于: Throwable;
Error 的子类表示系统很难恢复的错误(eg:堆内存溢出(内存泄漏)),一旦出现Java虚拟机就崩溃了,程序就无法执行了。
Exception 的子类是系统可恢复异常,是一种设计或实现问题,它表示如果程序运行正常,从不会发生的的情况。一旦出现异常只要使用代码进行适当的处理程序就可以恢复继续执行。
RuntimeException:非检查异常,是系统不检查的异常,Java编译器不检查RuntimeException和其子类的异常,无论是抛出和捕获都不检查。这类异常需要程序员编程需要避免的异常。
常见异常有:
NullPointerException:当操作一个空引用时会出现此错误。
NumberFormatException:数据格式转换出现问题时出现此异常。
ClassCastException:强制类型转换类型不匹配时出现此异常。
ArrayIndexOutOfBoundsException:数组下标越界,当使用一个不存在的数组下标时出现此异常。
常用API
try(){//java7 实现了autocloseable接口的类实例可以防止try后的()里来自动关闭.比如流
//可能抛出异常的代码块
}catch(Exception e){ //catch块使用的是一个新的线程,同时也可以作为分支的流程控制
e.getMassage();//获取错误信息
e.printStactTrace();//打印异常堆栈详细信息
}finally{
//无论是否出异常,finally块必走
}
自定义异常
自定义异常,通常用来说明业务逻辑上的错误。自定义原则:通过异常的名字可以知道错误的原因.Java异常机制可以保证程序更安全和更健壮。虽然Java类库已经提供很多可以直接处理异常的类,但是有时候为了更加精准地捕获和处理异常以呈现更好的用户体验,需要开发者自定义异常。
通过Eclipse来自动生成相应的构造方法。具体步骤如下:
- 声明一个自定义异常类并继承自Exception或者RuntimeException
- 右键点击Source
- 选择Generate Constructors from Superclass
- 选中父类中所有构造方法后确认生成,对适宜的构造方法进行重写
- 点出提示的***和继承的方法
其他
多线程
注意点
- 守护线程又称为后台线程、 精灵线程.默认创建的线程都不是守护线程;守护线程使用与普通线程没区别,但是结束时机上有一个区别之处,即:当进程结束时,所有正在运行的守护线程即使没运行完毕也会强制结束.GC就是运行在一个守护线程上的;
进程的结束:当一个进程中所有普通线程都结束时,进程结束. - interrupt()方法是线程的一个方法,用于中断线程,但是若线程处于阻塞状态时是中断阻塞,若线程没有处于阻塞状态则线程直接被中断.
- 同步运行:代码执行有先后顺序(单线程运行是同步,多线程也可以进行同步运行操作);
异步运行:代码各执行各的(多线程下运行代码是异步的) - 多线程并发安全问题:当多个线程并发运行操作同一数据时,由于线程切换的时机不可控,可能会导致操作该数据时的过程未按照程序设计的执行顺序运行,导致操作出现混乱,严重时 可能会导致系统瘫痪.当一个方法是用synchronized修饰后,那么该方法变为"同步方法",多个线程不能同时进入方法内容运行.而必须有顺序的一个一个运行.这样就可以避免并发安全问题.
- 线程池主要完成两个工作:
管理线程数量:由于每个线程有会占用一定的内存,线程数量过多会导致内存占用大,还有一个问题就是CPU过度切换,导致程序出现"卡顿".
重用线程:优化了线程频繁创建与销毁的现象.
常用API
//方法1
Thread t = new Thread(){ //thread实现了runnable接口,这种方法的缺点是受制于单一继承性与线程类和线程执行体直接的一对一强耦合使得线程无法重用
public void run(){
//线程执行逻辑
}
};
t.start();
//方法2
new Thread(new Runnable(){ //可以让多个线程共用同一资源,缺点是代码复杂度相对提高
public void run(){
//线程执行逻辑
}
}).start();
//静态方法
Thread curt = Thread.currentThread(); //返回当前线程
Thread.sleep(1000);//线程睡眠1000ms
Thread.yield();//放弃当前CPU时间片,直接进入runnable状态,重新竞争CPU时间片
//实例方法
long id = curt.getId(); //得到线程标识符id,程序生命周期内不可改变
String name = curt.getName();//得到线程名字
int priority = curt.getPriority();//得到线程优先级1-10 默认5
boolean b1 = curt.isAlive();//线程是否活着
boolean b2 = curt.isDaemon();//线程是否是守护线程
boolean b3 = curt.isInterrupted();//线程是否中断
t.setDaemon(true);//设置t线程为守护线程,需要在线程启动前调用该方法
t.setPriority(5);//设定优先级(1-10 1最低 10最高) 3个常量 Thread.MAX_PRIORITY thread.MIN_PRIORITY thread.NORM_PRIORITY
t.interrupt();//打断阻塞继续运行或者正常运行时直接中断
t.join();//将t线程加入当前线程执,当当前线程执行到此句时,会进入阻塞状态,等待t线程执行完毕才会继续执行
Synchronized (同步监视器){
//上锁代码块
}//也可给方法上锁 同步监视器为调用该方法的对象
//线程池
ExecutorService threadPool = Executors.newFixedThreadPool(5);//创建最大线程数为5的线程池
threadPool.execute(t); //把线程任务分配给线程池
//停止线程池
threadPool.shutdown();//线程池不再接受新任务,在线程池所有任务执行完毕后销毁线程池
threadPool.shutdownNow();//线程池会调用所有线程的中断方法后立即停止.若有阻塞线程,经interrupt唤醒后执行完该次线程即停止.线程池不会销毁,可继续接受任务
其他
集合类
注意点
- 集合中存储的都是引用类型的元素(基本类型会自动转为包装类),引用类型变量实际上存储的是对象的“地址”,所以实际上集合只存储了元素对象在堆中的地址。而并不是将对象本身存入了集合中。引用类型加入集合后,原引用仍然存在(和集合使用同一个引用);
- 迭代器要求在遍历的过程中不允许通过集合的方法增删元素,否则会抛出异常.删除元素可以通过迭代器提供的remove方法删除,删除的是本次通过next方法迭代的元素
- 增强for循环遍历集合就是迭代器遍历集合,所以注意,遍历过程中不能通过集合方法增删元素
- Collections是java.util下的类,是针对集合的帮助类,提供一系列静态方法实现对各种集合的搜索,排序,线程安全化等操作。
- Iterator接口提供遍历任何Collection的接口。我们可以从一个Collection中使用迭代器方法来获取迭代器实例。迭代器取代了Java集合框架中的Enumeration。迭代器允许调用者在迭代过程中移除元素。
常用API
Colletion c = new ArrayList();//用实现类来测试collection的方法
boolean b1 = c.add("one");
int size = c.size();
boolean b2 = c.isEmpty(); //集合元素个数为0即为空集合
c.clear();//清空集合元素
c.contains(new String("one")); //true 用equals()比较
c.remove(new String("one"));//删除最前面那个 用equals()比较
//批处理
Collection c1 = new ArrayList();
boolean b3 = c.addAll(c1);//把c1整个加入集合c
boolean b4 = c.removeAll(c1);//c中去除c和c1的交集
boolean b5 = c.containsAll(c1);//判断c中是否含c1的所有元素
//迭代器遍历
Iterator it = c.iterator();//获得迭代器
while(it.hasNext()){//问
System.out.println((String) it.next());//取
it.remove();//删
}
String[] arrs = c.toArray(new String[c.size()]);//集合转数组
List<String> list = Arrays.asList(arrs); //数组转集合 不能对转换的集合进行add,remove操作 对集合元素的操作就是对原数组元素操作
//集合的复制
List<String> list1 = new ArrayList<String>(list); //复制后的list1可随意操作
//collections工具类
Collections.sort(list); //集合升序排列
Collections.sort(list,new Comparator<String>(){ //使用比较器 匿名内部类
public int compare(String s1,String s2){
return s1.length()-s2.length();
}
});
List<String> list3 = Collections.synchronizedlist(list); //转换为线程安全的list
//list集合
list.add(1,"2");//按下标插入
String old = list.remove(1);//按下标删除,返回删除掉的元素
for(int i=0;i<list.size();i++){
System.out.println(list.get(i)); //按下标获取元素
}
String old2 = list.set(1,"3");//元素替换 返回被修改前的元素
List<String> sublists = list.subList(3,3+4);//截取子集合 对子集元素的操作就是对原集合的操作
//队列:先进先出
Queue<String> q = new LinkedList<String> ();
q.offer("one"); //进队
String str = q.poll();//出队
String str1 = q.peek();//引用队首元素
Deque<String> deque = new LinkedList<String>();
deque.offerfirst("x");//从队首入队
String str2 = deque.polllast();//从队尾出队
//栈:(队首)后进先出
Deque<String> stack = new LinkedList<String>();
stack.push("one");//进栈
String str3 = stack.pop();//出栈
String str4 = stack.peek();//判断栈顶元素
boolean b = stack.isEmpty();//判断空栈
//Map
Map<String,Integer> map = new HashMap<String,Integer>();
Integer d = map.put("语文",90); //存入或者替换 返回值为同key的value值,若不存在同key,则返回null
int size = map.size(); //键值对对数
int n = map.get("语文"); //得到value
Integer m = map.remove("语文"); //返回value值,若无存在的k-v键值对,则返回null
boolean b6 = map.containsKey("语文");
boolean b7 = map.containsValue(90);
Set<String> keyset = map.KeySet();// 得到所有key的set集合
Set<Entry<String,Integer>> entryset = map.entrySet();// 得到所有的k-v对
for(Entry<String,Integer> e : entryset){
System.out.println(e.getKey()+": "+e.getValue());
}
Collection<Integer> values = map.values(); //得到所有的value集合
//lambda遍历
map.keySet().forEach((k)->System.out.println(k+"\t"));
map.forEach((k,v)->System.out.println(k+": "+v));
map.values().forEach((v)->System.out.println(v));
其他
反射和注解
注意点
- Java 提供了一套API,提供了检查一个对象内部结构的手段;反射API可以动态加载类, 动态创建对象, 动态访问属性, 动态调用方法
- 静态执行: Java代码经过编译以后就确定的执行次序, 称为静态执行次序;
动态执行: 在运行期间才确定创建那个类的对象, 执行那个方法! - 反射的用途:解耦!
利用反射可以实现一段程序与未来一个类之间耦合在一起, 这段程序就与未来的类之间是松耦合的关系-- 也就是解耦了!
如: Eclipse 可以开发任何未来的程序, 解析任何未来程序的结构.
Eclipse利用反射技术实现快捷菜单, 可以使Eclipse与被开发的类解耦.
常用API
Class cls = obj.getClass();//得到类名
Field[] fields = cls.getDeclaredFields();//得到字段
Method[] methods = cls.getDeclaredMethods();//得到类里面的方法
Constructor[] constructors = cls.getDeclaredConstructor();//得到构造器
String className = "mypackage.Koo";//完整的包名.类名
Class c = Class.forName(className);//动态加载类
Field f = c.getDeclaredField(fieldName);//获取指定名字的字段
f.setAccessible(true);//设置为true可访问私有属性
Object obj = c.newInstance();
Method m = c.getDeclaredMethod(methodName);//获取指定方法名的方法
m.setAccessible(true);//设置为true可访问私有方法
Class[] type = m.getParameterTypes();//参数类型
String mName = m.getName();//得到方法名
Test test = m.getDeclaredFieldAnnotation(Test.class);
Object result = m.invoke(obj);//动态调用方法
Object[] paras = new Objet[]();
Object rr = m.invoke(obj,paras);//动态调用含参数的方法
其它
二进制
注意点
- 补码的互补对称现象 -n=~n+1 最小值除外
- 算术右移(>>)高位补符号位(按小的方向取结果),逻辑右移(>>>)高位补0
API
String str = Integer.toBinaryString(50);//看计算机里实际的2进制数(补码)
String str2 = Integer.toHexString(50);//16进制表示的字符串
其它
日期类
注意点
1.java.util.Calendar日历类
Calendar本身是一个抽象类,定义了日历类操作时间相关方法.其提供了一个静态方法getInstance()可以根据系统所在地区获取一个适用的实现类.大部分地区获取的都是GregorianCalendar,即:阳历.
常用API
Date d = new Date();//获得当前日期
long time = d.getTime();//获得1970年1月1日到此时此刻的毫秒值
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String str_date = sdf.format(d);//日期按格式转换为字符串
Date date2 = sdf.parse(str_date);//字符串转换为日期
Calendar c = Calendar.getInstance();
Date date = c.getTime();//得到日期
c.setTime(date);//设置日期
c.add(Calendar.Month,2);//日历时间的月+2 月份0-11
c.set(Calendar.DAY_OF_WEEK,Calendar.MONDAY);//设置为周一
int dd = c.get(Calendar.DAY_OF_WEEK)-1;//按时间分量获取值 -1之后对应日历表下标
int mm = c.getActualMaximum(Calendar.DAY_OF_MONTH);//当月实际天数
c.set(2018,8,8,20,8,8);//设置时间分量的值,可一次全部设置 超出某个时间分量最大值时,会进行进位
上一篇: Hi出行接口
下一篇: 编译QT的mysql驱动