集合类

来源:互联网 发布:原来你还在这里知乎 编辑:程序博客网 时间:2024/06/06 10:33


Collection
数组:可以存储对象和基本数据类型,长度固定
集合:只能存储对象(对象的类型可以不同),存储的是对象的引用,长度可变
集合框架为什么出现这么多的容器?
每一个容器对数据的存储方式不同,即存储的数据结构不同

共性方法

增add(Object o)多态接受Object类型,以便接收任意类型的对象,addAll(Collection c)向集合中添加一个集合中的元素删clear()清空集合,remove()删除元素 removeAll(Collection c) 去除与参数集合相同的元素retainAll(Collection c) 取与参数集合的交集判断contains 判断集合是否包含某个元素isEmpty()集合是否为空其他size()集合的容量   toArray()集合变成数组取出迭代器:由于从集合中取出元素的动作不能用一个方法实现,通过一个类来完成 定义内部类是因为可以直接操作集合的元素,且每个容器内部的数据结构不同 具体的操作细节也不同,但判断和取出的共性相同可以抽取出iterator接口。 得到这个内部类对象使用集合的iterator()方法返回方式一:Iterator it = new ArrayList().itrator(); while(it.hasNext())it.next();方式二:for(Iterator it = new ArrayList().itrator();it.hasNext();)it.next();//把迭代器对象定义成局部变量,节省内存<strong></strong>
list:元素有序,可以重复,因为该集合体系有索引
ArrayList:底层数据节后是数组。特点:查询速度快,增删慢。线程不同步。初始容量为10,50%延长,节约空间
LinkedList:链表数据结构。特点:增删速度快,查询慢
Vector:数组数据结构。线程同步,被ArrayList替代,初始容量为10,100%延长
List特有方法:凡是可以操作角标的方法都是该体系特有的

增add(index,element)   addAll(index,Collection)删 remove(index)改set(index,element)查get(index) subList(from,to) listIterator() int indexOf(obj)获取指定元素的位置   ListIterator listIterator()List集合特有迭代器ListIterator是Iterator的子接口List集合特有的获取元素的方式:for(int x = 0;x<al.size();x++)al.get(x);//list集合特有的通过角标获取
在迭代过程中不可以通过集合对象的方法操作集合中的元素,并发操作异常ConcurrentModificationException
所以迭代过程中只能用迭代器的方法操作元素,但是Iterator的方法是有限的,不能增加、修改等,需要使用其子接口ListIteraor,该接口只能通过List集合的ListIteraor方法获取
public static void main(String[] args){ArrayList al = new ArrayList();al.add("java01");al.add("java02");al.add("java03");al.add(2,"java04");//List集合特有,通过角标操作ListIterator li = al.listIterator();while(li.hasNext()){if(li.next().equals("java02")){//al.add("java");使用集合的方法出错li.add("java");  //ListIterator特有的方法li.set("java002");//ListIterator特有的方法}}}
LinkedList特有方法
addFrist();addLast();头部添加,尾部添加元素
getFrist();getLast();获取元素但不删除,如果集合为空,出现NoSuchElementExecption
removeFrist();removeLast();获取元素并删除,如果集合为空,出现NoSuchElementExecption

JDK1.6出现的代替方法
offerFrist();offerLast();
peekFrist();peekLast();获取元素但不删除,如果集合为空返回null
pollFrist();pollLast();获取元素并删除,如果集合为空返回null
LinkedList link = new LinkedList();link.offerFrist("java01");link.offerFrist("java02");link.offerFrist("java03");//[java03,java02,java01]link.peekLast()//返回Java01while(!link.isEmpty())  //LinkedList特有遍历方式,但遍历之后被清空link.pollFrist();
List集合判断元素是否相同,依据元素的equals(),remove().contains()方法都用到equals()
class Person{private String name;private int age;Person(String name,int age){this.name=name;  this.age=age;}public String getName(){ return name;}public String getAge(){ return age;}public boolean equals(Object o){//重写equals方法,集合判断时自动掉用if(!(o instanceof Person))//传Person的时候自动向上转型为Objectreturn false;Person p = (Person)o;//getName和getAge是person特有的方法,需要强转return this.name.equals(p.getName())&&(this.age==p.getAge());//其中的equals调用String的}}class Demo{public static void main(String[] args){ArrayList l = new ArrayList();l.add(new Person("aaa",20));l.add(new Person("aaa",20));l.add(new Person("bbb",30));l.add(new Person("bbb",50));l.add(new Person("ccc",40));l.remove(new Person("bbb",50));//使用了元素的equals方法,删除指定对象Iterator it = l.iterator();while(it.hasNext()){Person p = (Person)it.next();//next方法返回的也是Object类型System.out.println(p.getname()+p.getAge());}}public static ArrayList DelElements(ArrayList al){ArrayList newAl = new ArrayList();//创建新的ArrayListIterator it = l.iterator();while(it.hasNext()){Object obj = it.next();if(!newAl.contains(obj)) //使用了元素的equals方法,来判断是否有该元素newAl.add(obj);}return newAl;}}
Set:元素无序(存取顺序不一致),不可以重复
HashSet:底层数据结构是哈希表,线程非同步
判断是否是相同对象:
先调用hashCode()方法结果相同再调用equals()方法
先调用hashCode()方法结果不同不会调用equals()方法
数据结构不同所依赖的方法不同,remove和contains方法都使用hashcode和equals()
实际上因为Set元素不可以重复,add()方法也使用hashcode和equals()
class Person{private String name;private int age;Person(String name,int age){this.name=name;  this.age=age;}public String getName(){ return name;}public String getAge(){ return age;}public boolean equals(Object o){//重写equals方法,集合判断时自动掉用if(!(o instanceof Person))//传Person的时候自动向上转型为Objectreturn false;Person p = (Person)o;//getName和getAge是person特有的方法,需要强转return this.name.equals(p.getName())&&(this.age==p.getAge());//其中的equals调用String的}public int hashcode(){ //重写hashcode()方法,hashSet集合判断元素是否相同,先使用此方法//System.out.println("hashcode");return name.hashcode()+age*11;}}public static void main(String[] args){HashSet h = new HashSet();h.add(new Person("aaa",10));h.add(new Person("aaa",20));//添加元素时判断是否有此元素,先使用hashcode(),值相等在用equals判断h.remove(new Person("aaa",20));//元素删除时,若hashcode值不相等,肯定没有这个元素h\.contains(new Person("aaa",20));//也是先使用hashcode在使用equals}
TreeSet:可以对Set集合中的元素排序,底层数据结构二叉树,保证元素不重复的依据是:compareTo()或者compare()
第一种排序方式:让元素自身具备比较性,元素implements comparable接口,实现compareTo方法
第二种排序方式:的那个元素自身不具备比较性,或者具备的比较性不是说需要的,让集合自身具备比较性
在集合初始化时具备比较方式TreeSet(Comparator<? super E> comparator) ,定义一个类实现comparator,实现compare()
两种排序都存在时,以comparator为主
<span style="white-space:pre"></span>class Person implements Comparable{//实现Comparable接口,重写compareTo方法private String name;private int age;Person(String name ,int age){this.name = name;this.age=age;}public String getName(){ return name;}public String getAge(){ return age;}public int compareTo(Object obj){if(!(obj instanceof Person))throw new RuntimeException("不是Person");Person p = (Person)obj;return this.getName().compareTo(p.getName());}}class Mycomparator implements Comparator{//自定义比较器,实现Comparator接口,重写compare方法,不必重写equals,有继承自Object类的public int compare(Object o1,Object o2){Person p1 = (Person)o1;Person p2 = (Person)o2;return p1.getName().compareTo(p2.getName());}}class Demo{public static void main(String[] args){TreeSet ts = new TreeSet(new Mycomparator());//有比较器时不再使用Person中的compareTo方法ts.add(new Person("aaa",10));ts.add(new Person("aaaaa",20));//调用Mycomparator的compare方法}}
map:存储键值对,保证键的唯一性
Hashtable:底层是哈希表数据结构,不可以存入null键和值,线程同步,jdk1.0
HashMap:底层是哈希表数据结构,允许使用null键和值,线程不同步 ,jdk1.2效率高
TreeMap:二叉树数据结构,线程不同步,可以给map集合中的键排序
set底层使用了map集合
Map共性方法:

<span style="white-space:pre"></span>1、添加put(key,value)方法,添加相同键,后添加的值会覆盖原有的值,并返回原来的值putAll2、删除clear() remove(Object key)根据键删除,并返回键对应的值3、判断containsValue(Object Value)  containsKey(Object key) isEmpty()4、获取get(Object key)根据键得到值,通过返回null判断是否包含键 size()  values()返回所有值的集合map集合两种取出方式:1.keySet:将map中所有键存入到Set集合,set具有迭代器,通过迭代方法取出所有键· 再根据get方法获取每一个键对应的值2.Set<Map.Entry<k,v>>Map.Entry也是一个接口,是Map接口中的一个内部接口
class Demo{public static void main(String[] args){HashMap<String,String> hm = new HashMap<String,String>();hm.put("01","aa");hm.put("02","bb");hm.put("01","cc");//添加相同的键,value = "cc",此方法返回值"aa"if(hm.get("01")!=null)//get方法可以替换containsKey,如果没有相应的键,返回nullSystem.out.println(hm.get("01"));//第一种取出方式Set<String> s1 = hm.keySet();//返回键的Set集合Iterator<String> it1 = s1.iterator();while(it1.hasNext()){System.out.println(hm.get(it1.next()));}//第二种取出方式Set<Map.Entry<String,String>> s2 = hm.entrySet();//返回 键-值关系 的Set集合Iterator<Map.Entry<String,String>> it2 = s2.iterator();//Set集合中存放的是键-值的关系while(it2.hasNext()){Map.Entry<String,String> m = it2.next();//得到键-值对的对象Map.EntrySystem.out.println(m.getKey()); //调用Map.Entry的方法System.out.println(m.getValue());}}}
Collections:操作集合的工具类
     <T extends Comparable<? super T>> void sort(List<T> list);对List排序     <T> void sort(List<T> list,Comparator<? super T> c);自定义比较器对List排序      max(Collection<? extends T> coll) ;获取对象中的最大值      binarySearch(List<? extends Comparable<? super T>> list, T ke); 对List二分法查找,必须先排序      fill(List<? super <T> list, T obj);将集合中的元素全部换成obj      replaceAll(List<T> list, T oldVal, T newVal);      reverse(List<?> list);      reverseOrder();      synchronizedList(List<T> list); //源码中中对每一个操作都加锁       synchronizedMap(Map<K,V> m);      synchronizedSet(Set<T> s);        shuffle(List<?> list);使用默认随机源对指定列表进行置换

public void test(){ArrayList<String> al = new ArrayList<String>();al.add("cc");al.add("dd");al.add("aa");Collections.sort(al);//对list排序System.out.println(al);Collections.reverse(al);//反转元素System.out.println(al); }
Arrays:操作数组的工具类
binarySearch()使用二分搜索法来搜索指定的数组,以获得指定的值copyOfRange() 将指定数组的指定范围复制到一个新数组fill(a,val)  将指定的值分配给指定数组的每个元素<span style="color:#ff6666;">toString()  返回指定数组内容的字符串表示形式</span>sort()   对指定的数组按升序进行排序 <span style="color:#ff6666;">asList() ;把数组变成集合,判断元素时不必手工遍历,但是不可以使用集合的增删方法</span>
集合中只能存放对象
如果数组存放的引用类型,变成集合时数组中的元素直接变成集合元素
如果数组存放的基本数据类型,将数组作为集合中的元素。
public  void test{int[] arr = new int[]{3,1,2,5};Arrays.sort(arr);//对数组排序System.out.println(Arrays.toString(arr));//打印数组//List list = Arrays.asList(arr);//把数组当作集合中的元素//System.out.println(list);//打印[intxxxxInteger[] arr1 = new Integer[]{3,1,2,5};List<Integer> list = Arrays.asList(arr1);//集合中只能存放对象System.out.println(list);}
Collection--toArray(t[]):集合变数组
1、指定类型数组的长度定义多长?
当指定类型的数组长度小于集合的size,该方法内部会创建一个新的数组长度为size
当指定类型的数组长度大于集合的size,不创建数组而使用传进来的
2、为什么要把集合变成数组?
为了限定对元素的操作