黑马程序员-java集合类总结
来源:互联网 发布:java cst时间转换 编辑:程序博客网 时间:2024/06/05 23:02
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
一、集合类概述
1、为什么出现集合类
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储。集合就是存储对象最常用的一种方式。
2、数组和集合类同是容器,两者有何区别
数组虽然也可以存储对象,但其长度是固定的,数组中可以存储基本数据类型;集合长度是可变的,集合只能存储对象。
3、集合类的特点
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
4、集合类的关系图
1)java集合的框架大致可分为两大类,一类是Collection,另一类是Map。Collection接口实现了Iterator接口,即迭代器接口,这意味着Collection接口的实现类可以调用Iterator接口的方法实现迭代器行为。Collection和Map的不同之处在于,Collection类集合存储单个对象,而Map类集合存储两个对象的键值对。
2)java提供了Collections、Arrays两个工具类,提供诸如集合排序、数组和集合的互换等功能。
3)Collection接口下又分为List接口与Set接口。List接口的主要实现类为ArrayList、LinkedList、Vector;Set接口的主要实现类为HashSet、TreeSet、LinkedHashSet。
二、Collection
1、常见操作
因为Collection为接口,不能建立对象,我们以ArrayList为例,
例1:
import java.util.*;class Test {public static void main(String[] args) {ArrayList al=new ArrayList();//添加元素al.add("java01");al.add("java02");al.add("java03");//打印集合System.out.println("原集合:"+al);//判断元素System.out.println("java03是否存在:"+al.contains("java03"));System.out.println("集合是否为空:"+al.isEmpty());//获取个数,即集合长度System.out.println("Size="+al.size());//删除元素al.remove("java02");System.out.println("删除后集合:"+al);//清空集合al.clear();System.out.println("清空后集合:"+al);}}
输出结果:
原集合:[java01, java02, java03]java03是否存在:true集合是否为空:falseSize=3删除后集合:[java01, java03]清空后集合:[]
2、迭代器
什么是迭代器呢?其实就是集合取出元素的方式。
例2:
import java.util.*;class Test {public static void main(String[] args) {ArrayList al=new ArrayList();al.add("AAA");al.add("BBB");al.add("CCC");//获取迭代器Iterator it=al.iterator();while (it.hasNext()){System.out.println(it.next());}}}
输出结果:
AAABBBCCC
元素是有序的,元素可以重复。因为该集合体系有索引。
1、List特有方法:凡是可以操作角标的方法都是该体系特有的方法。
例3:
import java.util.*;class Test {public static void main(String[] args) {ArrayList al=new ArrayList(); //添加元素al.add("java001");al.add("java002");al.add("java003");al.add("java004");al.add("java005");//List特有方法//在指定位置添加元素al.add(1,"java");//删除指定位置元素al.remove(2);//修改元素al.set(2,"java007");//通过角标获取元素for (int x=0;x<al.size() ;x++ ){System.out.println("al("+x+")="+al.get(x));}}}输出结果:
al(0)=java001al(1)=javaal(2)=java007al(3)=java004al(4)=java005
2、List特有的迭代器:ListIterator
在迭代时,不可以通过集合对象的方法操作集合中的元素,否则会发生ConcurrentModificationException(并发修改异常)。所以,在迭代时,只能用迭代器的方法操作元素。然而,Iterator提供的方法十分有限,只能对元素进行判断、取出及删除的操作。如果想要进行其他的操作,如添加、修改等,就需要使用其子接口:ListIterator。
该接口只能通过List集合的listIterator()方法获取。
例4:
import java.util.*;class Test {public static void main(String[] args) {ArrayList al=new ArrayList(); //添加元素al.add("java001");al.add("java002");al.add("java003");al.add("java004");al.add("java005");//并发修改异常/*Iterator it=al.iterator();while(it.hasNext()){Object obj=it.next();if(obj.equals("java002"))al.add("java007"); //错误,并发修改异常}*///利用ListIterator在迭代过程中,添加\修改\删除元素ListIterator lit=al.listIterator();while (lit.hasNext()){Object obj=lit.next();if(obj.equals("java002"))lit.add("java008"); //正确,不会发生并发修改异常System.out.println("obj="+obj);}System.out.println(al);}}
输出结果:
obj=java001obj=java002obj=java003obj=java004obj=java005[java001, java002, java008, java003, java004, java005]
Collection
|--List:元素是有序的,元素可以重复,因为该集合体系有索引。
|--ArrayList:底层使用数组数据结构。特点:查询速度很快,但是增删稍慢。线程不同步。
|--LinkedList:底层使用链表数据结构。特点:增删速度很快,查询稍慢。
|--Vector:底层使用数组数据结构。特点:线程同步,被ArrayList替代了。
1)ArrayList:
基于数组实现的,可以理解为可变数组,允许null元素,集合内部的元素顺序排列。
2)LinkedList:
基于双向链表实现的,允许null元素。通过提供特有的offerFirst()、peekFirst()、pollFirst()等方法,使LinkedList可用于模拟堆栈(stack)、队列(queue)或双向队列(deque)数据结构。
例5:使用LinkedList模拟一个队列数据结构。队列:先进先出
class DuiLie{private LinkedList ll;DuiLie(){ll=new LinkedList();}public void add(Object obj){ll.addFirst(obj);}public Object get(){return ll.removeLast();}public boolean isEmpty(){return ll.isEmpty();}public int size(){return ll.size();}public void sop(){for (int x=0;x<ll.size() ;x++ ){System.out.println(ll.get(x));}}}
延伸阅读:请参阅When to use LinkedList<> over ArrayList<>?来了解,两种集合的使用场合。
3)Vector
Vector非常类似ArrayList,两者的主要区别在于,Vector是同步的,而ArrayList不同步。因此,在性能上Vector稍差于ArrayList。
4、List集合判断元素是否相同的依据
List集合根据元素的equals()来判断元素是否相同。contains()、remove()等方法在判断集合中的元素是否为目标元素时,也是调用equals()方法。
例6:
import java.util.*;class Test {public static void main(String[] args) {//去除重复学生案例ArrayList al=new ArrayList();al.add(new Student("A",1));al.add(new Student("A",1));al.add(new Student("B",1));al.add(new Student("B",1));al.add(new Student("B",1));al.add(new Student("B",2));al.add(new Student("C",3));al.add(new Student("C",3));System.out.println("old:"+al);al=SingleElement(al);System.out.println("new:"+al);}//去除重复元素。此例证明,List集合通过equals()方法判断元素是否相同。//即,contains(),remove()方法,底层调用的都是equals()方法;public static ArrayList SingleElement(ArrayList al){ArrayList newAl=new ArrayList();Iterator it=al.iterator();while (it.hasNext()){Object obj=it.next();if(!newAl.contains(obj))newAl.add(obj);}return newAl;}}class Student{private String name;private int age;Student(String name,int age){this.name=name;this.age=age;}//复写equals方法,学生的名字和年龄都相同时才认为两者相同public boolean equals(Object obj){if (!(obj instanceof Student))return false;Student st=(Student)obj;return (this.name.equals(st.name))&&(this.age==st.age);}public String toString(){return "("+this.name+","+this.age+")";}}
输出结果:
old:[(A,1), (A,1), (B,1), (B,1), (B,1), (B,2), (C,3), (C,3)]new:[(A,1), (B,1), (B,2), (C,3)]
四、Set
Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。
|--HashSet:底层使用哈希表数据结构。线程是非同步的
|--TreeSet:底层使用二叉树数据结构。可以对元素进行排序。
1、HashSet:
底层使用哈希表数据结构。线程是非同步的。
保证元素唯一性原理:判断元素的hashCode值是否相同,若相同,则继续通过equals方法判断元素是否相同。
两个元素相同,则它们的hashCode值一定相同,但若两个元素不相同,则它们的hashCode值不一定不相同。
例7:
import java.util.*;class Test {public static void main(String[] args) {/*去除重复学生案例2/*此例证明,HashSet集合通过hashCode()、equals()方法判断元素是否相同。/*即,contains(),remove()方法,底层调用的都是这两个方法;/******************************************************************/HashSet hs=new HashSet();hs.add(new Student("A",1));hs.add(new Student("A",1));hs.add(new Student("B",1));hs.add(new Student("B",1));hs.add(new Student("B",1));hs.add(new Student("B",2));hs.add(new Student("C",3));hs.add(new Student("C",3));System.out.println("Set:"+hs);}}class Student{private String name;private int age;Student(String name,int age){this.name=name;this.age=age;}//复写equals方法,学生的名字和年龄都相同时才认为两者相同public boolean equals(Object obj){if (!(obj instanceof Student))return false;Student st=(Student)obj;return (this.name.equals(st.name))&&(this.age==st.age);}//复写hashCode方法public int hashCode(){return name.hashCode()+age*37;}public String toString(){return "("+this.name+","+this.age+")";}}
输出结果:
Set:[(A,1), (B,1), (B,2), (C,3)]
2、TreeSet
底层使用二叉树数据结构。可以对元素进行排序。
保证元素唯一性的原理:compareTo()方法返回0,则认为两个元素相同。
TreeSet有两种排序方式:
1)元素自身具有比较性
方法:让元素所属的类继承Comparable接口,并重写compareTo()方法,则元素自身就具有了比较性。这种方式也称为元素的自然顺序。
例8:
import java.util.*;class Test {public static void main(String[] args) {TreeSet ts=new TreeSet();ts.add(new Student("asd",20));ts.add(new Student("aasdfd",10));ts.add(new Student("gedd",22));ts.add(new Student("re",23));ts.add(new Student("2013d",12));ts.add(new Student("x",9));System.out.println("排序后"); //即添加元素时,集合自动排序Iterator it=ts.iterator();while (it.hasNext()){Student s=(Student)it.next();System.out.println(s.getName()+"..."+s.getAge());}}}//TreeSet第一种排序法,让元素具有比较性class Student implements Comparable{private String name;private int age;Student(String name,int age){this.name=name;this.age=age;}//复写compareTo方法,以学生的年龄为主要条件,姓名为次要条件,升序排序public int compareTo(Object obj){if(!(obj instanceof Student))throw new RuntimeException();Student s=(Student)obj;System.out.println(s.name+"..."+s.age);int num=new Integer(this.age).compareTo(new Integer(s.age));if(num==0)return this.name.compareTo(s.name);return num;}public String toString(){return name+"@"+age;}public String getName(){return name;}public int getAge(){return age;}}
输出结果:
asd...20asd...20asd...20asd...20gedd...22asd...20aasdfd...10asd...20aasdfd...10排序后x...9aasdfd...102013d...12asd...20gedd...22re...23
由结果可知,1)TreeSet在添加元素时,会利用compareTo方法依次与集合中已有的元素进行比较;2)根据compareTo方法的返回值判断两个元素的先后顺序,从而完成排序。
2)让集合自身具有比较性
当元素自身不具有比较性,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性。
方法:自定义一个比较器类继承Comparator接口,重写compare()方法。
例9:
import java.util.*;class Test {public static void main(String[] args) {TreeSet ts=new TreeSet(new MyComparator());//构造TreeSet时,传入自定义比较器ts.add(new Student("asd",20));ts.add(new Student("aasdfd",10));ts.add(new Student("gedd",22));ts.add(new Student("re",23));ts.add(new Student("2013d",12));ts.add(new Student("x",9));System.out.println("排序后"); //即添加元素时,集合自动排序Iterator it=ts.iterator();while (it.hasNext()){Student s=(Student)it.next();System.out.println(s.getName()+"..."+s.getAge());}}}//TreeSet第一种排序法,让元素具有比较性class Student implements Comparable{private String name;private int age;Student(String name,int age){this.name=name;this.age=age;}//复写compareTo方法,以学生的年龄为主要条件,姓名为次要条件,升序排序public int compareTo(Object obj){if(!(obj instanceof Student))throw new RuntimeException();Student s=(Student)obj;System.out.println(s.name+"..."+s.age);int num=new Integer(this.age).compareTo(new Integer(s.age));if(num==0)return this.name.compareTo(s.name);return num;}public String toString(){return name+"@"+age;}public String getName(){return name;}public int getAge(){return age;}}//TreeSet第二种排序方法,让集合具有比较性class MyComparator implements Comparator{//重写compare方法,以学生名字的长度为主要条件,学生的年龄为次要添加,升序排序public int compare(Object o1,Object o2){Student s1=(Student)o1;Student s2=(Student)o2;int num=new Integer(s1.getName().length()).compareTo(new Integer(s2.getName().length()));if(num==0)return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));return num;}}
输出结果:
排序后x...9re...23asd...20gedd...222013d...12aasdfd...10由结果可知,TreeSet采用第二种排序方式时,是根据比较器中的compare()方法来对元素进行比较排序的。
五、Map
Map:该集合存储键值对,而且键值不可重复。
|--HashTable:底层是哈希表数据结构,不可以存入null键和null值。该集合是线程同步的,效率低。
|--HashMap:底层是哈希表数据结构,允许存入null键和null值。该集合是不同步的,效率高。
|--TreeMap:底层是二叉树数据结构。线程不同步。可以给集合中的键进行排序。
Map和Set很像,其实Set的底层就是使用Map实现的。
1、基本功能
例10:
import java.util.*;class Test {public static void main(String[] args) {//基本功能HashMap<String,String> hm=new HashMap<String,String>();//添加元素。如果添加时,键相同,则该键对应的值会覆盖原有键对应的值,并返回原来的值System.out.println(hm.put("01","A"));System.out.println(hm.put("01","D"));hm.put("02","B");hm.put("03","C");System.out.println(hm.containsKey("01"));//判断是否包含某键System.out.println(hm.get("01")); //通过键查找对应的值Collection<String> coll=hm.values(); //获得Map集合中所有的值System.out.println(coll);System.out.println(hm);}}
输出结果:
nullAtrueD[D, B, C]{01=D, 02=B, 03=C}2、取出元素方式
Map集合提供两种取出方式:
1)Set<K> keySet():将Map中所有的键存入到一个Set集合。Set集合具备迭代器,可以通过迭代方式取出所有的键,然后再用get()方法获取每一个键对应的值。
2)Set<Map.Entry<K,V>> entrySet():将Map中的所有映射关系存入到一个Set集合中,而这个映射关系的数据类型就是:Map.Entry
例11:
import java.util.*;class Test {public static void main(String[] args) {//学生案例TreeMap<Student,String> hm=new TreeMap<Student,String>(new StuNameComparator());hm.put(new Student("AAA",20),"BeiJing");hm.put(new Student("B",22),"HangZhou");hm.put(new Student("CC",23),"ChengDu");//第一种取出方式Set<Student> ks=hm.keySet(); //先获取Map集合的所有键的Set集合:keySet()Iterator<Student> it=ks.iterator(); //获取迭代器while (it.hasNext()){Student s=it.next();String add=hm.get(s); //有了键,通过Map集合的get()方法获取其对应的值System.out.println(s+"..."+add);}//第二种取出方式Set<Map.Entry<Student,String>> es=hm.entrySet(); //将Map集合中的映射关系存入到Set集合中,entrySet()Iterator<Map.Entry<Student,String>> it2=es.iterator();while (it2.hasNext()){Map.Entry<Student,String> me=it2.next();Student s=me.getKey(); //Map.Entry特有的获取键的方法String str=me.getValue(); //Map.Entry特有的获取值的方法System.out.println(s+"///"+str);}}}class Student implements Comparable<Student>{private String name;private int age;Student(String name,int age){this.name=name;this.age=age;}public String getName(){return name;}public int getAge(){return age;}public boolean equals(Object obj){if(!(obj instanceof Student))throw new RuntimeException();Student s=(Student)obj;return this.name.equals(s.name)&&this.age==s.age;}public int hashCode(){return name.hashCode()+10*age;}public int compareTo(Student s){int num=this.name.compareTo(s.name);if(num==0)return new Integer(this.age).compareTo(new Integer(s.age));return num;}public String toString(){return name+"@"+age;}}class StuNameComparator implements Comparator<Student>{public int compare(Student s1,Student s2){int num=new Integer(s1.getName().length()).compareTo(new Integer(s2.getName().length()));if(num==0)return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));return num;}}
输出结果:
B@22...HangZhouCC@23...ChengDuAAA@20...BeiJingB@22///HangZhouCC@23///ChengDuAAA@20///BeiJing
六、Collections与Arrays工具类
1、Collections
对Collection类集合进行操作的工具类。
常见方法:
static <T extends Comparable<? super T>> void sort(List<T> list) //对List进行排序static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) //根据比较器的排序,返回集合中的最大元素static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key) //以二分法的形式,在List集合中查找某元素static <T> void fill(List<? super T> list, T obj) //将集合中的元素全部替换成指定元素例12:
import java.util.*;class CollectionsTest{public static void main(String[] args) {ArrayList<String> list=new ArrayList<String>();list.add("fcg");list.add("defd");list.add("aa");list.add("aaa");list.add("d");//sort()System.out.println("排序前:"+list);Collections.sort(list,new StrLenComparator());System.out.println("排序后:"+list);//反转Collections.reverse(list);System.out.println("reverse后:"+list);//max()System.out.println("默认max:"+Collections.max(list));System.out.println("根据比较器的max:"+Collections.max(list,new StrLenComparator()));//binarySearch()System.out.println("aaa在第"+Collections.binarySearch(list,"aaa")+"个");//fill(),全部替换Collections.fill(list,"aa");System.out.println("fill后:"+list);//replaceAllCollections.replaceAll(list,"aa","bb");System.out.println("replaceAll后:"+list);}}class StrLenComparator implements Comparator<String>{public int compare(String str1,String str2){int num=new Integer(str1.length()).compareTo(new Integer(str2.length()));if(num==0)return str1.compareTo(str2);return num;}}
输出结果:
排序前:[fcg, defd, aa, aaa, d]排序后:[d, aa, aaa, fcg, defd]reverse后:[defd, fcg, aaa, aa, d]默认max:fcg根据比较器的max:defdaaa在第2个fill后:[aa, aa, aa, aa, aa]replaceAll后:[bb, bb, bb, bb, bb]
延伸阅读:
关于 Java Collections API 您不知道的 5 件事,第 1 部分与关于 Java Collections API 您不知道的 5 件事,第 2 部分
2、Arrays
用于操作数组的工具类。
我们只介绍其中一个:
数组变集合:
static <T> List<T> asList(T... a) //将数组转成集合将数组转成List集合后,可以使用集合的思想和方法操作数组中的元素,但不可以使用集合的增删方法。因为数组的长度是固定的。
集合变数组:
Collection中的方法:
public <T> T[] toArray(T[] a) //将集合转成数组将集合转成数组后,就限定了对元素的操作,不能再进行增删操作了。
例13:
import java.util.*;class CollectionsTest{public static void main(String[] args) {//数组变集合String[] arr={"a","bb","ccc"};List<String> list=Arrays.asList(arr);//list.add("dddd");//错误,不能使用集合的增删功能ArrayList<String> newList=new ArrayList<String>(Arrays.asList(arr));newList.add("dddd");//OK!System.out.println(list);//数组变集合2int[] num={1,2,3};System.out.println(Arrays.asList(num));//数组元素必须为对象,否则只将该数组作为集合中的元素存在Integer[] num2={1,2,3};System.out.println(Arrays.asList(num2));//这样就没问题了//集合变数组String[] arr1=list.toArray(new String[list.size()]);for (String str:arr1){System.out.print(str+" ");}}}
输出结果:
[a, bb, ccc][[I@188edd79][1, 2, 3]a bb ccc
延伸阅读:
欲深入了解ArrayList、HashMap、HashSet等的实现原理,请参考
深入Java集合学习系列:ArrayList的实现原理等系列。
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com
- 黑马程序员-Java基础-集合类总结
- 黑马程序员-java集合类总结
- 黑马程序员---java集合总结
- 黑马程序员---java集合总结
- 黑马程序员-java集合总结
- 黑马程序员:Java基础总结----集合框架的工具类
- 黑马程序员 知识点总结-Java集合框架工具类
- 黑马程序员java基础篇----集合总结
- 黑马程序员:Java基础总结----Map集合
- 黑马程序员--javaSE--java集合容器总结
- 黑马程序员之java--集合框架总结
- 黑马程序员---Java基础总结--集合
- 【黑马程序员】java集合框架学习总结
- 黑马程序员java自学总结之--集合
- 黑马程序员 java基础--map集合总结
- 黑马程序员----java基础---集合总结
- 黑马程序员--集合Set总结--java
- 黑马程序员--集合List总结--java
- 黑马程序员-java IO的文件合并
- 代码生产myeclips注册码
- Getting Started with Qt5 for Android
- Android利用LocalSocket实现Java端进程与C端进程之间的IPC
- ITFriend月刊-第1期-2014年6月.pdf
- 黑马程序员-java集合类总结
- 用java打tar包
- JavaSE(12):7k面试之交通灯管理系统
- 数字游戏
- Navicat连接Linux虚拟机的MySQL
- [Markdown]sublime markdown preview使用
- MappedByteBuffer的使用
- chromium编译
- C++ namespace 命名空间