JAVA集合框架
一:集合框架概述
1、什么是JAVA集合框架?
JAVA集合框架是为了表示和操作集合而规定的一种统一的标准体系结构。
2、什么时候要使用JAVA集合框架?
需要更复杂的方式存储对象或者程序运行时并不知道有多少对象,可以使用集合框架。
3、使用集合框架的好处?
1>提高程序设计效率
2>提高程序速度和质量
3>集合框架鼓励软件的复用
4、集合框架包含的内容?
任何集合框架包含三个部分的内容:对外的接口,接口实现类,集合运算的算法
二:集合框架
1、JAVA中集合框架里常用集合的继承关系
2、JAVA中集合框架所有集合的继承关系
三:Collection接口
JAVA集合可分为Collection和Map两大体系。Collection接口是JAVA集合的一个根接口与Map接口属于同一个级别,不过在一般使用中很少直接使用Collectino接口。如果使用Collection接口必须要用其实现类实例化。同时,Collection接口有两个子接口:List和Set。而且,要知道集合里装的对象,如果是基本数据类型JVM会自动执行装箱/拆箱。
1、Collection的常用方法
2、Collection的常用方法示例
package cn.gson.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* Collection集合
* @author Administrator
*
*/
public class CollectionTest {
public static void main(String[] args) {
CollectionTest cl = new CollectionTest();
cl.fun();
}
public void fun(){
//实现类ArrayList类实例化Collection
Collection coll = new ArrayList();
Collection coll1 = new ArrayList();
//使用add()方法向集合添加对象
coll.add(1);
coll.add("小华");
coll.add('a');
coll1.add(1);
coll1.add(3);
System.out.println("add()方法:"+coll);
//使用addAll()方法向集合添加一组对象
coll.addAll(coll1);
System.out.println("addAll()方法:"+coll);
//使用size()方法查询集合里对象的个数
coll.size();
System.out.println("size()方法:"+coll);
//使用contains()方法查询集合里是否包含某个对象
boolean flag = coll.contains("小华");
System.out.println("contains()方法:"+flag);
//使用containsAll()方法查询集合里是否包含一组对象
flag = coll.containsAll(coll1);
System.out.println("containsAll()方法:"+flag);
//使用isEmpty()方法查询集合是否为空
flag = coll.isEmpty();
System.out.println("isEmpty()方法:"+flag);
//使用retainAll()方法保留与该集合里对象相同的对象
System.out.println("retainAll()方法:"+coll.retainAll(coll1));
//使用remove()方法删除指定对象
coll.remove(1);
System.out.println("remove()方法:"+coll);
//使用removeAll()方法删除指定一组对象
coll.removeAll(coll1);
System.out.println("removeAll()方法:"+coll);
//使用clear()方法删除所有对象
coll.clear();
System.out.println("clear()方法:"+coll);
}
public void fun1(Collection coll){
//使用迭代器遍历集合
Iterator it = coll.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
public void fun2(Collection coll){
//使用foreach遍历集合
for (Object object : coll) {
System.out.println(object);
}
}
public void fun3(Collection coll){
//使用toArray()转换成对象数组
Object[] obj = coll.toArray();
for (int i = 0; i < obj.length; i++) {
System.out.println(obj[i]);
}
}
}
3、示例运行结果
四、List接口
List接口为Collection接口的子接口,它在Colletion接口的基础上扩充一些方法。List的实现类有ArrayList,LinkList,Vector。同时,Set接口需要使用实现类实例化。List接口的特点:元素有序,可重复,可以为null。
1、List接口扩充的方法
2、List接口扩充方法示例
package cn.gson.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
* list接口
* @author Administrator
*
*/
public class ListTest {
public static void main(String[] args) {
ListTest lt = new ListTest();
lt.fun();
}
private void fun() {
List list = new ArrayList();
for(int i=0;i<6;i++){
list.add(i);
}
System.out.println("list:"+list);
//1.使用add(index,element)在指定位置增加元素
list.add(3, 8);
System.out.println("list.add(index,element):"+list);
//2.使用indexOf(index)返回指定元素在集合中第一次出现时的下标
int index = list.indexOf(8);
System.out.println("list.indexOf(index):"+index);
//3.使用remove(index)删除指定位置的元素
list.remove(3);
System.out.println("list.remove(index):"+index);
//4.使用subList()截取集合
list.subList(0, 3);
System.out.println("list.subList():"+list.subList(0, 3));
}
//方法1:转化为对象数组遍历
private void getArrayList(Collection coll){
Object[] obj = coll.toArray();
for (int i = 0; i < obj.length; i++) {
System.out.println(obj[i]);
}
}
//方法2:使用ListIterator迭代器遍历(List)
private void getListIteratorList(Collection coll,Object obj){
ListIterator lt = (ListIterator) coll.iterator();
//正向遍历
while(lt.hasNext()){
System.out.println(lt.next());
if(lt.next() == obj){
//删除 元素
lt.remove();
//修改元素
lt.set(1);
}
}
//反向遍历
while(lt.hasPrevious()){
System.out.println(lt.previous());
if(lt.next() == obj){
//删除 元素
lt.remove();
//修改元素
lt.set(1);
}
}
}
//方法3:foreac遍历集合
private void getForList(Collection coll){
for (Object object : coll) {
System.out.println(object);
}
}
//方法4:Iterator迭代器遍历集合(相比较ListIterator而言Iterator没有set()方法)
private void getIteratorList(Collection coll,Object obj){
Iterator it = coll.iterator();
while(it.hasNext()){
System.out.println(it.next());
if(it.next() == obj){
it.remove();
}
}
}
//方法5:使用get()方法遍历集合(List)
private void getGetList(Collection coll){
List list = (List) coll;
for(int i=0;i
3、示例运行结果
4、ArrayList,LinkList,Vector实现类的区别
在一般的使用中通常用ArrayList,查询速度比较快,如果增删比较频繁则使用LinkedList,,Vector不建议使用,效率太低。
ArrayList:底层的数据结构为数组,ArrayList的使用可以和数组做类比,很多地方有相似之处。所以它的查询速度比较快,但是增加和删除操作效果并不好,因为增加或删除对象后面的所有的对象的位置都要移动,在尾部操作除外。它相对于数组的定长改进在于当达到集合容量临界点时会自动扩增当前容量的额1.5倍,不过这样带来的坏处在于如果不估计好容量会造成资源的浪费。JDK1.2后存在并且线程不同步。
LinkedList:底层的数据结构为链表,它的增删操作比较快,线程不同步。
Vector:底层数据结构为数组,JDK1.0后存在并且线程同步,因为效率比较低后被ArrayList代替。
5、ArrayList与Vector的比较
五:Set接口
Set接口就与我们所学的数学中的集合相同了,它里面不允许有重复的值出现。继承Collection接口,但并有向List那样扩充方法,它的方法与Collection接口相同。Set接口常用的实现类有:HashSet,TreeSet,LinkedHashSet。同时,Set接口需要使用实现类实例化。
Set接口的特点:元素无序,不能重复,可以为null。
1、Set接口的方法示例
package cn.gson.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
/**
* set接口
* @author Administrator
*
*/
public class SetTest {
public static void main(String[] args) {
SetTest st = new SetTest();
st.fun();
st.fun2();
st.fun3();
st.fun4();
}
//HashSet
private void fun2() {
Set st = new HashSet();
for (int i = 0; i < 5; i++) {
st.add(i);
}
st.add(1);
st.add("a");
st.add("b");
st.add(null);
System.out.println("HashSet插入顺序:"+st);
}
//LinkedHashSet
private void fun3() {
Set st = new LinkedHashSet();
for (int i = 0; i < 5; i++) {
st.add(i);
}
st.add(1);
st.add("a");
st.add("b");
st.add(null);
System.out.println("LinkedHashSet插入顺序:"+st);
}
//TreeSet
private void fun4() {
Set st = new TreeSet();
for (int i = 0; i < 5; i++) {
st.add(i);
}
st.add(1);
st.add(9);
st.add(6);
System.out.println("TreeSet插入顺序:"+st);
}
//ArrayList
private void fun() {
Collection st = new ArrayList();
for (int i = 0; i < 5; i++) {
st.add(i);
}
st.add(1);
st.add("a");
st.add("b");
st.add(null);
System.out.println("ArrayList插入顺序:"+st);
}
}
2、示例运行结果
3、HashSet,TreeSet,LinkedHashSet的区别
HashSet:采用HashSet实现Set接口,它的插入顺序是无序的。向HashSet里添加对象时,会对象调用hashCoe()方法得到相应的hash码,然后再通过hash算法对元素进行存储和查询。同时由于实现hash算法所以它的插入和查询效率比较高。HashSet判断插入对象是否相等的方法是equals(),如果它们相等它们的hashCode()方法返回值也相等。
LinkedHashSet:它是HashSet的子类,与HashSet不同的时,它会保留元素插入时的顺序,可以有null值,插操作的性能不如HashSet,但迭代操作比较效率比较好。
TreeSet:TreeSet是SortedSet接口的实现类。TreeSet可以确保集合处于排序状态,它提供两种排序方式:自然排序,定制排序,缺省排序为自然排序。
4、hashCode()方法
5、自然排序
TreeSet实现自然排序会自动调用元素的compareTo()方法进行对元素之间的大小比较,并且会按升序排列。如果一个类的对象要加入到TreeSet中,除了该集合的第一个元素以外,其他元素必须实现comparable接口,同时重写compareTo()方法。同时,它只会比较同一类的对象。
6、自然排序示例
package cn.gson.collection.entity;
/**
* Student实体类
* @author Administrator
*
*/
public class Student implements Comparable{
private String name;
private int 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;
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Student() {
super();
}
@Override
public int compareTo(Object o) {
int flag = 0;
Student stu = (Student) o;
if(this.age > stu.age){
flag = 1;
}
else if(this.age < stu.age){
flag = -1;
}
return flag;
}
}
7、示例运行结果
8、定制排序
定制排序会用到comparator接口,实现这个接口的类需要重写compare(T a,T b)这个方法。如果a>b返回值1,如果a<b返回值-1,如果a=b返回值0。同时,它只会比较同一类的对象。
9、定制排序示例
package cn.gson.collection.entity;
import java.util.Comparator;
/**
* 实现Comparator接口
* @author Administrator
*
*/
public class ComparatorTest implements Comparator
{
@Override
public int compare(Student o1, Student o2) {
int flag = 0;
if(o1.getAge() > o2.getAge()){
flag = 1;
}
else if(o1.getAge() < o2.getAge()){
flag = -1;
}
return flag;
}
}
package cn.gson.collection.entity;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
/**
* TreeSet实现类
* @author Administrator
*
*/
public class TreeSetTest {
public static void main(String[] args) {
TreeSetTest tt = new TreeSetTest();
tt.fun();
}
private void fun(){
Set
ts = new TreeSet<>();
ts.add(new Student("小王",25));
ts.add(new Student("小刘",20));
ts.add(new Student("小明",30));
ts.add(new Student("小华",18));
this.fun1(ts);
System.out.println("------------");
List
lt = new ArrayList<>();
lt.add(new Student("小王",25));
lt.add(new Student("小刘",20));
lt.add(new Student("小明",30));
lt.add(new Student("小华",18));
ComparatorTest ct = new ComparatorTest();
Collections.sort(lt, ct);
this.fun1(lt);
System.out.println("------------");
Collections.reverse(lt);
this.fun1(lt);
}
private void fun1(Collection
coll){
for (Student student : coll) {
System.out.println(student.getName()+student.getAge());
}
}
}
10、示例运行结果
六:Map接口
Map接口与Colleciton接口属于同一级别,它是以键和值得方式存放数据,键不能重复但值可以,因为Map中的键是以set的形式来存放,不过他们同时都能为null。我们可以把Map简单的看做一张数据库的表,id作为唯一主键。键和值得类型可以是任意的引用类型,一般键都用String类型。Map的常用实现类:HashMap,TreeMap,LinkedHashMap,一般使用HashMap示例化Map。Map接口的特点:键值对应,键不能重复,键值可以为null。
1、Map的常用方法
2、Map常用方法示例
package cn.gson.collection;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Map接口
* @author Administrator
*
*/
public class MapTest {
public static void main(String[] args) {
MapTest mt = new MapTest();
mt.fun();
}
private void fun() {
Map map = new HashMap();
//使用put()方法向Map中添加值
map.put(1, 1);
map.put(1, 2);
map.put(3, 1);
map.put(4, 3);
map.put(null, null);
System.out.println("map:"+map);
//使用get()方法得到指定键的对应的值
map.get(1);
System.out.println("map.get():"+map.get(1));
//使用keySet()获得所有的键
Set set = map.keySet();
System.out.println("map.keySet():"+set);
//使用values()方法获得所有的值
Collection coll = map.values();
System.out.println("map.values():"+coll);
//使用remove()方法删除指定键的值
map.remove(1);
System.out.println("map.remove():"+map);
//使用entrySet()方法将Map集合转换为Set
Set st = map.entrySet();
System.out.println("map.entrySet():"+st);
}
}
3、示例运行结果
4、HashMap,TreeMap,LinkedHashMap的区别
HashMap:HashMap可以结合HashSet来理解,它的存取得顺序是按Hash算法来实现的,因此它的存取效果比较好。判断键唯一的标准:equals()=true和hashCode()=0,判断值相等:equals()。
LinkedHashMap:HashMap的子类,可以和LinkedHashSet来理解,采用链式存取迭代效果比较好,它保证了元素存储时的先后顺序。
TreeMap:可以结合TreeSet来理解,使用它得到是键有序的集合。并且可以根据需求得到想要的顺序。
5、HashMap,HashTable的比较?