Java集合
集合概述 为了使程序方便地存储和操纵数目不固定的一组数据,JDK类库中提供了Java集合,所有Java集合类都位于java.util包中。与Java数组不同,Java集合不能存放基本数据类型,而只能存放对象的引用。为了表达方便,我们简称对象。 Java集合主要包括三种类型:Set(集),List(列表),Map(映射)。
Java集合类框图 Collection Set List AbstractCollection SortedSet AbstractList AbstracSet AbstractSquentialList Vector TreeSet HashSet LinkedList 接口 抽象类 具体类 继承 实现
Java集合类框图 Map HashMap SortedMap LinkedHashMap TreeMap 接口 抽象类 具体类 继承 实现
Collection和Iterator接口 在Collection接口中声明了适用于Java集合(只包括Set和List)的通用方法。因此Set和List对象可以调用以上方法,Map对象不可以。 Iterator接口隐藏了底层集合的数据结构,向客户程序提供了遍历各种数据集合的统一接口。 如果集合中的元素没有排序,Iterator遍历集合中元素的顺序是任意的,并不一定与集合中加入元素的顺序是一致的。
Set(集) Set是最简单的集合,集合中的对象不按照特定的方式排序,并且没有重复的对象。Set接口主要有两个实现类:HashSet和TreeSet。 1 5 7 2 8 6 4 3 Set(集)
Set的一般用法 Set集合中存放的是对象的引用,并且没有重复对象。 Java中实现Set接口的类很多,至于该用哪个,我们不用区分,我们只对接口负责。 这样就创建了一个集合对象,我们把它当作抽象的集合接口看待。 使用接口的好处在于,实现类将来可以被替换,而程序不用做很多改动。 Set set=new HashSet();
Set的一般用法 Set集合依次把三个引用变量加入到集合中。 Set<String> set=new HashSet<String>(); String s1=new String(“Hello”); String s2=new String(“Hello”); String s3=new String(“World”); set.add(s1); set.add(s2); set.add(s3); System.out.println(set.size()); //对象的数目为2
Set的一般用法 Set集合存放某单位员工的名单,Set集合中元素的数目是不固定的。 Set<String> emp=new HashSet<String>(); emp.add("Tom"); emp.add("Mike"); emp.add("Jack"); emp.remove("Tom"); emp.remove("Jack"); emp.add("Linda"); System.out.println(emp.size()); //对象的数目为2
HashSet类 HashSet类按照哈希算法来存取集合中的对象,具有很好的存取和查找性能。 当向集合中加入一个对象时,HashSet会调用对象的hashCode()方法来获得哈希码,然后根据哈希码进一步计算出对象在集合中的位置。
散列技术的原理 把对象的哈希码直接用一个固定的公式计算,得出存储位置的方法。 优点是:可以快速命中搜索的目标。 26 15 22 最简单的哈希码公式:模 9 运算 冲突的解决方案:顺序检测 0 1 2 3 4 5 6 7 8 26 15 22 24
HashSet类 在Object类中定义hashcode()和equals()方法。如果object1.equals(object2)为true,那么object1和object2的哈希码也肯定相同。 为保证HashSet正常工作,要求当两个对象用equals()方法比较的结果为true时,它们的哈希码也相等。
TreeSet类 TreeSet类实现了SortedSet接口,能够对集合中的对象进行排序。 Set<Integer> set = new TreeSet<Integer>(); set.add(new Integer(8)); set.add(new Integer(6)); set.add(new Integer(7)); Iterator<Integer> it = set.iterator(); while (it.hasNext()) { System.out.println(it.next() + " "); } 输出结果为:6 7 8
TreeSet类 当向集合中加入一个对象时,会把它插入到有序的对象集合中。
自然排序 在JDK类库中,有一部分类实现Comparable接口,如Integer、Double和String等 Comparable接口有一个compareTo(Object o)方法,它返回整数类型。 对于表达式x.compareTo(y),如果返回值为0,则表示x和y相等,如果返回值大于0,则表示x大于y,如果返回值小于0,则表示x小于y。
自然排序 TreeSet调用对象的compareTo()方法比较集合中对象的大小,然后进行升序排列,这种方式称为自然排序。 JDK类库中实现了Comparable接口的一些类的排序方式。 类 排序 Byte、Double、Float、Integer、Long、Short 按数字大小排序 Character 按字符Unicode值的大小排序 String 按字符串中字符的Unicode值的大小排序
自然排序 使用自然排序时,只能向TreeSet集合中加入同一类型的对象,并且这些对象必须实现Comparable接口。 对于TreeSet集合中已经存在的对象,如果修改它们的属性,则TreeSet不会对它重新排序。
客户化排序 Java.util.Comparator<Type>接口提供具体的排序方式,<Type>指定被比较的对象的类型,Comparator有个compare(Type x,Type y)方法,用于比较两个对象的大小。 compare(x, y)的返回值为0,则表示x和y相等,如果返回值大于0,则表示x大于y,如果返回值小于0,则表示x小于y。
客户化排序 如果希望TreeSet按照Customer对象的name属性进行降序排列,可以先创建一个实现Comparator接口的类CustomerComparator。 CustomerComparator类就是一个自定义的比较器。
List(列表) List的主要特征是按照元素以线性方式存储,允许集合中存放重复对象。List接口的主要实现类包括:ArrayList和LinkedList。 ArrayList:代表长度可以变化的数组。允许对元素进行快速的随机访问,但是向ArrayList中插入与删除元素速度较慢。 10 15 21 65
List(列表) LinkedList:双向链表。向LinkedList中插入和删除元素的速度较快,随机访问的速度较慢。它单独具有addFirst() 、addLast()、getFirst()、getLast()、removeFirst()、removeLast()方法。 10 15 21 56
访问List中的元素 List中的对象按照索引位置排序,程序可以按照对象在集合中的索引位置来检索对象。 List<Integer> list= new ArrayList<Integer>(); list.add(new Integer(3)); list.add(new Integer(4)); list.add(new Integer(2)); for(int i=0;i<list.size();i++){ System.out.print(list.get(i)+” ”); } Iterator<Integer> it = list.iterator(); while (it.hasNext()) { System.out.print(it.next()+” ”);
为List排序 List只能对集合中的对象按索引顺序排序,如果希望对List中的对象按照其他特定的方式排序,可以借助Comparator接口和Collections类。 Collections类是对Java集合类库中的辅助类,它提供操纵集合的各种静态方法。 sort(List list):对List中的对象进行自然排序。 sort(List list,Comparator comparator):对List中的对象进行客户化排序, comparator参数指定排序方式。
为List排序 List<Integer> list= new ArrayList<Integer>(); list.add(new Integer(3)); list.add(new Integer(4)); list.add(new Integer(2)); Collections.sort(list); for(int i=0;i<list.size();i++){ System.out.print(list.get(i)+” ”); }
ListIterator接口 List的listIterator()方法返回一个ListIterator对象, ListIterator接口继承了Iterator接口,此外还专门提供了专门操纵列表的方法。 add():向列表中插入一个元素 hasPrevious():判断列表中是否还有上一个元素 previous():返回列表中的上一个元素
Vector Vector类可以实现动态的对象数组。几乎与ArrayList相同。
Map(映射) Map(映射):集合中的每一个元素包含一对键对象和值对象,集合中没有重复的键对象,值对象可以重复。 K3---->v2
Map(映射) 向Map集合中加入元素时,必须提供一对键对象和值对象。 Map的两个主要实现类:HashMap和TreeMap。
Map(映射) Map最基本的用法,就是提供类似字典的能力。 在Map中检索元素时,只要给出键对象,就会返回值对象。 Map<String,String> map=new HashMap<String,String>(); map.put("1","Monday"); map.put("one","Monday"); map.put("2","Tuesday"); map.put("3","Wensday"); System.out.println(map.get(“1")); System.out.println(map.get("one"));
Map接口中的方法 public Set keySet(): 返回键的集合。 public Set<Map.Entry<k,v>> entrySet(): 返回“键值对”的集合。 Map.Entry的对象代表一个“词条”,就是一个键值对。可以从中取值或键。
Map接口中的方法 举例:反向查字典。 Map<String,String> map=new HashMap<String,String>(); map.put("1","Monday"); map.put("one","Monday"); map.put("2","Tuesday"); map.put("3","Wensday"); Set x=map.entrySet(); Iterator i=x.iterator(); while(i.hasNext()){ Map.Entry en=(Map.Entry)i.next(); String key=(String)en.getKey(); String value=(String)en.getValue(); System.out.println(key+" "+value); }
HashMap HashMap按照哈希算法来存取键值对象。 为了保证HashMap能正常工作,和HashSet一样,要求当两个键对象通过equals()方法比较为true时,这两个键对象的hashCode()方法的返回的哈希码也一样。
TreeMap TreeMap实现了SortedSet接口,能够对的键对象进行排序。支持自然排序和客户化排序。 Map<String,String> map=new TreeMap<String,String>(); map.put("1","Monday"); map.put("one","Monday"); map.put("2","Tuesday"); map.put("3","Wensday"); Set<String> keys=map.keySet(); Iterator<String> it=keys.iterator(); while(it.hasNext()){ String key=it.next(); String value=map.get(key); System.out.println(key+" "+value); }