03-JavaAPI
目录:
01:JavaAPI简介
02:JavaAPI文档的使用
03:JavaAPI各包的用途
04:String,StringBuilder,StringBuffer三者的区别
05:StringBuffer扩容机制
06:常见容器类扩容机制
07:java集合类
01:JavaAPI简介
运行Java程序时, 虚拟机 装载程序的 class文件 所使用的Java API class文件。所有被装载的class文件(包括从应用程序中和从Java API中提取的)和所有已经装载的动态库(包含本地方法)共同组成了在Java虚拟机上运行的整个程序。 在一个平台能够支持Java程序以前,必须在这个特定平台上明确地实现API的功能。为访问主机上的本地资源,Java API调用了本地方法。由于Java API class文件调用了本地方法,Java程序就不需要再调用它们了。通过这种方法,Java API class文件为底层 主机 提供了具有平台无关性、标准接口的Java程序。对Java程序而言,无论平台内部如何,Java API都会有同样的表现和可预测的行为。正是由于在每个特定的主机平台上明确地实现了Java 虚拟机 和Java API,因此,Java程序自身就能够成为具有平台无关性的程序。
02:JavaAPI文档的使用
达内API查询网址:http://doc.tedu.cn/jdk6-docs/index.html
外网 API查询网址:在线文档-jdk-zh
03:JavaAPI各包的用途
java.awt包
AWT 是Abstract Window ToolKit (抽象窗口工具包)的缩写,这个工具包提供了一套与本地图形界面进行交互的接口。AWT 中的图形函数与操作系统所提供的图形函数之间有着一一对应的关系,当我们利用 AWT 来构件图形用户界面的时候,实际上是在利用操作系统所提供的图形库。AWT 所提供的图形功能是各种通用型操作系统所提供的图形功能的交集。java.beans包 java bean 操作相关的包
java.io包
java中io操作的包,通过数据流、序列化和文件系统提供系统输入和输出。
java.lang包
java.lang包包含了java开发的基础类和一些基本的方法。其中最重要的类就是java.lang.Object类,它的对象是Java平台中所有其他类对象扩展层次树的根
java.math包
一些数学及科学计算相关的包,提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类。
java.net包
java 网络通讯,如socket等操作
java.nio包
nio是java New IO的简称,在jdk1.4里提供的新api。Sun官方标榜的特性如下:
为所有的原始类型提供(Buffer)缓存支持。
字符集编码解码解决方案。
Channel:一个新的原始I/O抽象。
支持锁和内存映射文件的文件访问接口。
提供多路(non-bloking)非阻塞式的高伸缩性网络I/O。
java.rmi包
Java远程方法调用,即Java RMI(Java Remote Method Invocation)是java编程语言里,一种用于实现远程过程调用的应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程方法调用特性使Java编程人员能够在网络环境中分布操作。RMI全部的宗旨就是尽可能简化远程接口对象的使用。
java.security包
java.security包为安全框架提供类和接口。通过该包中的Java实现,仅仅能够完成消息摘要算法的实现(消息摘要处理的MessageDigest、DigestInputStream和DigestOutputStream类),并且其源代码是可见的。
java.sql包
提供使用 JavaTM 编程语言访问并处理存储在数据源(通常是一个关系数据库)中的数据的 API。此 API 包括一个框架,凭借此框架可以动态地安装不同驱动程序来访问不同数据源
java.text包
提供类和接口处理文本、日期、数字和消息的方式独立的自然语言。
java.util包
java的常用工具类,包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。
注:如果想详细知道具体每个包的作用请看如下链接:
Java API 各个包的内容解释 - 雪山上的蒲公英 - 博客园
04:String,StringBuilder,StringBuffer三者的区别
一、Java String 类——String字符串常量
字符串广泛应用 在Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。
需要注意的是,String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间。我们来看一下这张对String操作时内存变化的图:
我们可以看到,初始String值为“hello”,然后在这个字符串后面加上新的字符串“world”,这个过程是需要重新在栈堆内存中开辟内存空间的,最终得到了“hello world”字符串也相应的需要开辟内存空间,这样短短的两个字符串,却需要开辟三次内存空间,不得不说这是对内存空间的极大浪费。为了应对经常性的字符串相关的操作,就需要使用Java提供的其他两个操作字符串的类——StringBuffer类和StringBuild类来对此种变化字符串进行处理。
二、StringBuffer 和 StringBuilder 类——StringBuffer、StringBuilder字符串变量
当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
三者的继承结构
三者的区别:
(1)字符修改上的区别(主要)
String: 不可变字符串;
StringBuffer: 可变字符串、 效率低、线程安全;
StringBuilder:可变字符序列、效率高、线程不安全;
(2)初始化上的区别,String可以空赋值,后者不行,报错
①String
StringBuffer s = null;
StringBuffer s = “abc”;
②StringBuffer
StringBuffer s = null; //结果警告:Null pointer access: The variable result can only be null at this location
StringBuffer s = new StringBuffer();//StringBuffer对象是一个空的对象
StringBuffer s = new StringBuffer(“abc”);//创建带有内容的StringBuffer对象,对象的内容就是字符串”
小结:
(1)如果要操作少量的数据用 String;
(2)多线程操作字符串缓冲区下操作大量数据 StringBuffer;
(3)单线程操作字符串缓冲区下操作大量数据 StringBuilder(推荐使用)。
05:StringBuffer扩容机制
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
//同样有final修饰,因此不能被修改继承了。
//继承与AbstractStringBuilder,看下他源码,一个抽象类,并且源码中,
//也有valve数组,只是这里是char[] value;不是private final;而是没有加修饰词,
//则是dafault类型,默认类型,只准许下同一个包下面的类改。(封装知识)
//因为StringBulider是继承父类的,因此也有value数组,等等一些东西。
构造方法;
public StringBuffer() {
super(16);
}
直接调用父类的构造方法;
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
因此这个构造方法就是创建了一个为16的数组、默认16;
public StringBuffer(int capacity) {
super(capacity);
}
同样还是调用上面那个继承的方法,但是值不是16了,而是自己传入的。
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
传入一个字符串,那么他字符串的长度就是这个字符串的长度再加16;
并且还调用了append()方法,(就是累加的意思)然后这个方法里面用调用父类的append方法,父类的方法中用调用了很多方法,这些都可以进行点击其源码进行了解。Ctrl+点击;
StringBuilder sb = new StringBuilder();//字符数组长度为16,默认;
StringBuilder sb1 = new StringBuilder(32);//那么字符数组的长度就是32;
StringBuilder sb2 = new StringBuilder("asrh");
//4+16;并且在value[]={‘a', 's','r','h',/u0000.........}
append()方法。在StringBuilder中很常用的一种方法。对字符串进行追加。
并且他还有很多重载方法。
1
sb2.append("123");//就进行了追加了,因此也验证了这是可变字符数列。
sb2.append(true);//在后面就直接添加ture了。
System.out.println(sb2);//返回asrh123true
2
public synchronized StringBuffer append(String str) {
super.append(str);
return this;
}
注意一下append方法中有很多return this。这样有什么好处呢。
通过return this可以实现方法链;
StringBuilder sb3 = new StringBuilder("asrh");
sb3.append("12").append("345");//可以进行叠加就是因为返回的是this、
System.out.println(sb3);//输出asrh12345
这个也解决了前面那个String中的问题,怎么去为字符串追加字符。其实用StringBuilder是最好的。
在append追加的时候,如果出现容量问题时是怎么解决的。
进去源码里面找。
子类append都会调用父类的append,则进入父类的append方法中看。
父类源码中有ensureCapacityInternal(count + len);//确保容量;
在点进源码,有expandCapacity(minimumCapacity);//扩容。
//则进行扩容了,不是真的这个数组扩容了,而是用新的进行了替换。
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;//注意扩展的是两倍加2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();//抛出异常;
newCapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value, newCapacity);
}
//同样数组大小定义了是不能再变的了,因此要重新建一个数组。在copyOf方法里面定义了一个新的数组。
public static char[] copyOf(char[] original, int newLength) {
char[] copy = new char[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
后面讲的容器也是这样的思路来进行扩容的。
小结:
-
StringBuilder是jdk1.5引进的,而StringBuffer在1.0就有了;
-
StringBuilder和StringBuffer都是可变的字符串。能够通过append或者insert等方法改动串的内容;
-
StringBuffer是线程安全的而StringBuilder不是,因而在多线程的环境下优先使用StringBuffer,而其它情况下推荐使用StringBuilder,由于它更快。
-
StringBuilder和StringBuffer都继承自AbstractStringBuilder类,AbStractStringBuilder主要实现了扩容、append、 insert方法。StrngBuilder和StringBuffer的相关方法都直接调用的父类。
-
StringBuilder和StringBuffer的初始容量都是16,程序猿尽量手动设置初始值。以避免多次扩容所带来的性能问题;
-
StringBuilder和StringBuffer的扩容机制是这种:首先试着将当前数组容量扩充为原数组容量的2倍加上2,假设这个新容 量仍然小于预定的最小值(minimumCapacity),那么就将新容量定为(minimumCapacity),最后推断是否溢出,若溢出,则将容量定为整型的最大值0x7fffffff。
06:常见容器类扩容机制
类名 |
增长速率 |
初始值 |
ArrayList |
1.5x+1 |
默认10 |
Vector |
2x |
默认10 |
HashTable |
2x+1 |
默认11 |
HashMap |
2x |
默认16 |
StringBuffer |
2x+2 |
默认16 |
StringBuilder |
2x+2 |
默认16 |
07:java集合类
1. Interface Iterable
迭代器接口,这是Collection类的父接口。实现这个Iterable接口的对象允许使用foreach进行遍历,也就是说,所有的Collection集合对象都具有"foreach可遍历性"。这个Iterable接口只
有一个方法: iterator()。它返回一个代表当前集合对象的泛型<T>迭代器,用于之后的遍历操作
1.1 Collection
Collection是最基本的集合接口,一个Collection代表一组Object的集合,这些Object被称作Collection的元素。Collection是一个接口,用以提供规范定义,不能被实例化使用
1) Set
Set集合类似于一个罐子,"丢进"Set集合里的多个对象之间没有明显的顺序。Set继承自Collection接口,不能包含有重复元素(记住,这是整个Set类层次的共有属性)。
Set判断两个对象相同不是使用"=="运算符,而是根据equals方法。也就是说,我们在加入一个新元素的时候,如果这个新元素对象和Set中已有对象进行注意equals比较都返回false,
则Set就会接受这个新元素对象,否则拒绝。
因为Set的这个制约,在使用Set集合的时候,应该注意两点:1) 为Set集合里的元素的实现类实现一个有效的equals(Object)方法、2) 对Set的构造函数,传入的Collection参数不能包
含重复的元素
1.1) HashSet
HashSet是Set接口的典型实现,HashSet使用HASH算法来存储集合中的元素,因此具有良好的存取和查找性能。当向HashSet集合中存入一个元素时,HashSet会调用该对象的
hashCode()方法来得到该对象的hashCode值,然后根据该HashCode值决定该对象在HashSet中的存储位置。
值得主要的是,HashSet集合判断两个元素相等的标准是两个对象通过equals()方法比较相等,并且两个对象的hashCode()方法的返回值相等
1.1.1) LinkedHashSet
LinkedHashSet集合也是根据元素的hashCode值来决定元素的存储位置,但和HashSet不同的是,它同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的。
当遍历LinkedHashSet集合里的元素时,LinkedHashSet将会按元素的添加顺序来访问集合里的元素。
LinkedHashSet需要维护元素的插入顺序,因此性能略低于HashSet的性能,但在迭代访问Set里的全部元素时(遍历)将有很好的性能(链表很适合进行遍历)
1.2) SortedSet
此接口主要用于排序操作,即实现此接口的子类都属于排序的子类
1.2.1) TreeSet
TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态
1.3) EnumSet
EnumSet是一个专门为枚举类设计的集合类,EnumSet中所有元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显式、或隐式地指定。EnumSet的集合元素也是有序的,
它们以枚举值在Enum类内的定义顺序来决定集合元素的顺序
2) List
List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List集合允许加入重复元素,因为它可以通过索引来访问指定位置的集合元素。List集合默认按元素
的添加顺序设置元素的索引
2.1) ArrayList
ArrayList是基于数组实现的List类,它封装了一个动态的增长的、允许再分配的Object[]数组。
2.2) Vector
Vector和ArrayList在用法上几乎完全相同,但由于Vector是一个古老的集合,所以Vector提供了一些方法名很长的方法,但随着JDK1.2以后,java提供了系统的集合框架,就将
Vector改为实现List接口,统一归入集合框架体系中
2.2.1) Stack
Stack是Vector提供的一个子类,用于模拟"栈"这种数据结构(LIFO后进先出)
2.3) LinkedList
implements List<E>, Deque<E>。实现List接口,能对它进行队列操作,即可以根据索引来随机访问集合中的元素。同时它还实现Deque接口,即能将LinkedList当作双端队列
使用。自然也可以被当作"栈来使用"
3) Queue
Queue用于模拟"队列"这种数据结构(先进先出 FIFO)。队列的头部保存着队列中存放时间最长的元素,队列的尾部保存着队列中存放时间最短的元素。新元素插入(offer)到队列的尾部,
访问元素(poll)操作会返回队列头部的元素,队列不允许随机访问队列中的元素。结合生活中常见的排队就会很好理解这个概念
3.1) PriorityQueue
PriorityQueue并不是一个比较标准的队列实现,PriorityQueue保存队列元素的顺序并不是按照加入队列的顺序,而是按照队列元素的大小进行重新排序,这点从它的类名也可以
看出来
3.2) Deque
Deque接口代表一个"双端队列",双端队列可以同时从两端来添加、删除元素,因此Deque的实现类既可以当成队列使用、也可以当成栈使用
3.2.1) ArrayDeque
是一个基于数组的双端队列,和ArrayList类似,它们的底层都采用一个动态的、可重分配的Object[]数组来存储集合元素,当集合元素超出该数组的容量时,系统会在底层重
新分配一个Object[]数组来存储集合元素
3.2.2) LinkedList
1.2 Map
Map用于保存具有"映射关系"的数据,因此Map集合里保存着两组值,一组值用于保存Map里的key,另外一组值用于保存Map里的value。key和value都可以是任何引用类型的数据。Map的key不允
许重复,即同一个Map对象的任何两个key通过equals方法比较结果总是返回false。
关于Map,我们要从代码复用的角度去理解,java是先实现了Map,然后通过包装了一个所有value都为null的Map就实现了Set集合
Map的这些实现类和子接口中key集的存储形式和Set集合完全相同(即key不能重复)
Map的这些实现类和子接口中value集的存储形式和List非常类似(即value可以重复、根据索引来查找)
1) HashMap
和HashSet集合不能保证元素的顺序一样,HashMap也不能保证key-value对的顺序。并且类似于HashSet判断两个key是否相等的标准也是: 两个key通过equals()方法比较返回true、
同时两个key的hashCode值也必须相等
1.1) LinkedHashMap
LinkedHashMap也使用双向链表来维护key-value对的次序,该链表负责维护Map的迭代顺序,与key-value对的插入顺序一致(注意和TreeMap对所有的key-value进行排序进行区
分)
2) Hashtable
是一个古老的Map实现类
2.1) Properties
Properties对象在处理属性文件时特别方便(windows平台上的.ini文件),Properties类可以把Map对象和属性文件关联起来,从而可以把Map对象中的key-value对写入到属性文
件中,也可以把属性文件中的"属性名-属性值"加载到Map对象中
3) SortedMap
正如Set接口派生出SortedSet子接口,SortedSet接口有一个TreeSet实现类一样,Map接口也派生出一个SortedMap子接口,SortedMap接口也有一个TreeMap实现类
3.1) TreeMap
TreeMap就是一个红黑树数据结构,每个key-value对即作为红黑树的一个节点。TreeMap存储key-value对(节点)时,需要根据key对节点进行排序。TreeMap可以保证所有的
key-value对处于有序状态。同样,TreeMap也有两种排序方式: 自然排序、定制排序
4) WeakHashMap
WeakHashMap与HashMap的用法基本相似。区别在于,HashMap的key保留了对实际对象的"强引用",这意味着只要该HashMap对象不被销毁,该HashMap所引用的对象就不会被垃圾回收。
但WeakHashMap的key只保留了对实际对象的弱引用,这意味着如果WeakHashMap对象的key所引用的对象没有被其他强引用变量所引用,则这些key所引用的对象可能被垃圾回收,当垃
圾回收了该key所对应的实际对象之后,WeakHashMap也可能自动删除这些key所对应的key-value对
5) IdentityHashMap
IdentityHashMap的实现机制与HashMap基本相似,在IdentityHashMap中,当且仅当两个key严格相等(key1 == key2)时,IdentityHashMap才认为两个key相等
6) EnumMap
EnumMap是一个与枚举类一起使用的Map实现,EnumMap中的所有key都必须是单个枚举类的枚举值。创建EnumMap时必须显式或隐式指定它对应的枚举类。EnumMap根据key的自然顺序
(即枚举值在枚举类中的定义顺序)