------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、集合框架
概念:集合框架是Java中为了方便对集合进行存储、操作而形成的体系。集合是针对对象最常见的一种存储形式。
数组和集合类同是容器,区别在哪里?
相同点:
集合和数组都是容器,都可一存储对象(对象引用)。
不同点:
数组长度固定,集合长度可变。
数组可以存储基本数据类型,集合却只能存储对象;
集合类的特点:集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。
集合框架常用类关系图:
为什么会有这么多容器?
答:因为每个容器对数据的存储方式都有所不同,这个存储方式就是常说的数据结构。
二、Collection接口 Collection 接口是集合框架中的顶层接口,所以其所有共性在其子接口中都可以得到体现。
集合类中常用的方法:
1、添加
add(E e): 向集合中添加该元素。
addAll(Collection extends E> c): 将指定集合中的所有元素都添加到此集合中。
2、删除
remove(Object o):从此集合中移除指定元素的单个实例,如果存在的话。
removeAll(Collection> c):移除此集合中那些也包含在指定集合中的所有元素
clear();清空集合中所有元素。
3、判断
contains(Object o): 判断集合中是否包含某个元素。
containsAll(Collection> c):判断该集合是否包含另一集合中的所有元素。
isEmpty():判断集合是否为空。
4、获取
iterator():返回在此集合的元素上进行迭代的迭代器。
size():获取集合长度。
5、取交集
retainAll(Collection> c):保留本集合与另一集合的交集。
6、集合变数组
toArray(T[] a) :返回包含此 collection 中所有元素的数组。
注意:toArray(T[] a)返回数组的运行时类型与指定数组的运行时类型相同。此方法充当了基于数组的 API 与基于 collection 的 API 之间的桥梁。如果指定的数组能容纳该 collection,则返回包含此 collection 元素的数组;否则,将分配一个具有指定数组的运行时类型和此 collection 大小的新数组;如果指定的数组能容纳 collection,并有剩余空间(即数组的元素比 collection 的元素多),那么会将数组中紧接 collection 尾部的元素设置为 null。所以数组长度与集合长度刚刚好最合适。
因为Collection中有iterator()方法,所以每一个子类集合对象都具备迭代器。每个集合都具备取出的方式,而这个方式不足以用一个方法来描述,所以把取出动作封装成一个对象。因为数据结构不同,每个取出对象中取出的实现方式也不一样。取出的方式就通过类被描述。
迭代器中的方法:
next():返回迭代的下一个元素。
hasNext():如果仍有元素可以迭代,则返回 true。
remove():从迭代器指向的 Collection 中移除迭代器返回的最后一个元素。
注意:
1、迭代器在Collcection接口中是通用的,它替代了Vector类中的Enumeration。迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException异常。迭代器的next方法返回值类型是Object,所以要记得类型转换。
2、在迭代时循环中next调用一次,就要hasNext判断一次。next连续调用两次可能会发生NoSuchElementException异常。
三、List接口
List接口是Collection的子接口。所以它在具备Collection共性的基础上,还有其自个儿的特性。它可以通过角标获取元素,也可以通过for循环获取元素。
List特有方法:
1、添加
add(int index,E element):在列表的指定位置插入指定元素。
addAll(int index, Collection extends E> c) :将指定 集合中的所有元素都插入到列表中的指定位置。
2、删除
remove(int index): 移除列表中指定位置的元素。
3、修改
set(int index, E element):用指定元素替换列表中指定位置的元素,返回以前在指定位置的元素。
4、查找
get(int index) :返回列表中指定位置的元素。
subList(int fromIndex, int toIndex): 返回列表中指定的范围内的部分列表,含头不含尾。
listIterator():返回此列表元素的列表迭代器。
listIterator(int index):从列表的指定位置开始返回列表中元素的列表迭代器。
ListIterator特有的方法:
add(E e):将指定的元素插入列表。
previous():返回列表中的前一个元素。
hasPrevious():如果逆向遍历列表,列表迭代器有多个元素,就返回 true。
set(E e):用指定元素替换 next 或 previous 返回的最后一个元素。
四、Vector类和Enumeration接口
Enumeration特有的方法:
hasMoreElements():测试此枚举是否包含更多的元素。
nextElement():如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。
可见其性能相当于迭代器,只不过方法比较少。
Vector特有方法:
elements() :返回此向量的组件的枚举。 返回的类型是Enumernation类型的。
所以对于Vector来说有以下取出元素方式:
1、for循环
2、迭代器
3、列表迭代器
4、get方法,遍历for循环
5、枚举
五、linkedList类
概念:底层数据结构是链表,查询慢,增删快,线程不安全,效率高。
特有的方法:
addFirst(E e):将指定元素插入此列表的开头。
addLast(E e):将指定元素添加到此列表的结尾。
getFirst():返回此列表的第一个元素。
getLast():返回此列表的最后一个元素。
removeFirst():移除并返回此列表的第一个元素。
removeLast():移除并返回此列表的最后一个元素。
注意:获取元素的这些方法。如果集合中没有元素,会出现 NoSuchElementException异常。
JDK1.6出现的新特性:
offerFirst(E e)
offerLast(E e)
peekFirst()
peekLast()
pollFirst()
pollLast()
用法与上面方法一致,但获取元素时,如果集合中没有元素,则会返回 null 。
LinkedList模拟队列代码:
1 import java.util.LinkedList; 2 3 public class LinkedListDemo { 4 /* 5 * 链表模队列,先进先出 6 */ 7 public static void main(String[] args) { 8 DuiLie dl = new DuiLie(); 9 dl.myAdd("aa"); 10 dl.myAdd("bb"); 11 dl.myAdd("cc"); 12 dl.myAdd("dd"); 13 14 System.out.println(dl.myGet()); 15 } 16 17 } 18 19 class DuiLie{ 20 private LinkedList link; 21 22 DuiLie(){ 23 link = new LinkedList(); 24 } 25 26 public void myAdd(Object obj){ 27 link.addFirst(obj); 28 } 29 30 public Object myGet(){ 31 return link.removeLast(); 32 } 33 34 public boolean isNull(){ 35 return link.isEmpty(); 36 } 37 }
六、ArrayList类
概念:底层数据结构是数组,查询快,增删慢,线程不安全,效率高。是List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null在内的所有元素。除了实现 List 接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。
ArrayList去除重复对象代码:
1 import java.util.ArrayList; 2 import java.util.Iterator; 3 4 public class ArrayListDemo { 5 6 /** 7 * 去除ArrayList的重复对象 8 */ 9 public static void main(String[] args) { 10 ArrayList al = new ArrayList(); 11 al.add("AA"); 12 al.add("BB"); 13 al.add("AA"); 14 al.add("BB"); 15 al.add("CC"); 16 17 System.out.println(getSingle(al)); 18 } 19 public static ArrayList getSingle(ArrayList al){ 20 ArrayList myAl = new ArrayList(); 21 Iterator it = al.iterator(); 22 while(it.hasNext()){ 23 Object obj = it.next(); 24 if(!myAl.contains(obj)) 25 myAl.add(obj); 26 } 27 return myAl; 28 } 29 } 30 /** 31 * 运行结果:[AA, BB, CC] 32 */
上面比较的是字符串,所以可以成功。如果比较自定义对象时,那么就会失败。这是因为contains()方法底层是由equals()方法实现的,而Object类中的equals()方法比的是内存地址,所以我们如果相比较自定义对象,就需要复写equals()方法。
七、Set接口
概念:一个不包含重复元素的 collection
特点:
1、无序(存入与取出的顺序不一致)
2、唯一(存入集合的元素唯一)
八、HashSet类
概念:不保证 set 的迭代顺序,特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
遍历HashSet代码:
1 public class HashSetDemo 2 2 { 3 3 public static void main(String[] args) 4 4 { 5 5 HashSeths = new HashSet (); 6 6 hs.add("AA"); 7 7 hs.add("BB"); 8 8 hs.add("CC"); 9 9 hs.add("BB"); 10 10 11 11 for (String s : hs) 12 12 { 13 13 System.out.println(s); 14 14 } 15 15 } 16 16 } 17 /* 18 *运行结果: 19 * BB 20 * AA 21 * CC 22 */
HashSet中存储自定义对象代码:
1 import java.util.*; 2 public class HashSetDemo 3 { 4 public static void sop(Object obj) 5 { 6 System.out.println(obj); 7 } 8 public static void main(String[] args) 9 { 10 HashSet hs = new HashSet(); 11 //向HashSet集合中添加元素 12 hs.add(new Person("a1",11)); 13 hs.add(new Person("a2",12)); 14 hs.add(new Person("a3",13)); 15 hs.add(new Person("a2",12)); 16 //对集合进行迭代 17 Iterator it = hs.iterator(); 18 while(it.hasNext()) 19 { 20 Person p = (Person)it.next(); 21 22 sop(p.getName()+"::"+p.getAge()); 23 } 24 } 25 } 26 //定义一个Person类 27 class Person 28 { 29 private String name; 30 private int age; 31 public String getName() 32 { 33 return name; 34 } 35 public int getAge() 36 { 37 return age; 38 } 39 Person(String name,int age) 40 { 41 this.name = name; 42 this.age = age; 43 } 44 //覆盖hashCode方法 45 public int hashCode() 46 { 47 return name.hashCode()+age*3; 48 } 49 //这里的equals是复写Object类里的equals方法 50 public boolean equals(Object obj) 51 { 52 if(!(obj instanceof Person)) 53 return false; 54 Person p = (Person)obj; 55 return this.name.equals(p.name) && this.age == p.age; 56 } 57 58 }
判断元素唯一性的方式:通过对象的hashCode和equals方法来完成元素唯一性
如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。
如果为true,视为相同元素,不存。如果为false,那么视为不同元素,就进行存储。
九、TreeSet类
概念:使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。
遍历TreeSet代码:
1 public class TreSetDemo 2 { 3 public static void main(String[] args) 4 { 5 TreeSetts = new TreeSet (); 6 ts.add(22); 7 ts.add(17); 8 ts.add(24); 9 ts.add(19); 10 ts.add(18); 11 ts.add(20); 12 ts.add(18); 13 ts.add(23); 14 15 16 for(Integer i : ts) 17 { 18 System.out.print(i+" "); 19 } 20 } 21 } 22 //运行结果:17 18 19 20 22 23 24
TreeSet中对自定义对象进行排序:
1 package filetools; 2 3 import java.util.*; 4 /** 5 * 定义一个学生类,使可以按照姓名和年龄排序。 6 * 7 */ 8 public class TreeSetDemo 9 { 10 public static void main(String[] args) 11 { 12 //定义一个TreeSet集合并添加元素 13 TreeSet ts = new TreeSet(new MyCompare()); 14 15 ts.add(new Student("sa01",22)); 16 ts.add(new Student("sb01",21)); 17 ts.add(new Student("sc09",20)); 18 ts.add(new Student("sc09",19)); 19 ts.add(new Student("sc06",18)); 20 ts.add(new Student("sb06",18)); 21 ts.add(new Student("sd07",29)); 22 Iterator it = ts.iterator(); 23 while(it.hasNext()) 24 { 25 Student stu = (Student)it.next(); 26 System.out.println(stu.getName()+"..."+stu.getAge()); 27 } 28 } 29 } 30 //定义学生类 31 class Student implements Comparable 32 { 33 private String name; 34 private int age; 35 36 public String getName() 37 { 38 return name; 39 } 40 public int getAge() 41 { 42 return age; 43 } 44 Student(String name,int age) 45 { 46 this.name = name; 47 this.age = age; 48 } 49 public int compareTo(Object obj) 50 { 51 if(!(obj instanceof Student)) 52 throw new RuntimeException("不是学生对象"); 53 Student s = (Student)obj; 54 55 if(this.age>s.age) 56 return 1; 57 if(this.age==s.age) 58 { 59 return this.name.compareTo(s.name); 60 } 61 return -1; 62 } 63 64 } 65 66 //定义一个比较器 67 class MyCompare implements Comparator 68 { 69 //覆盖compare方法 70 public int compare(Object o1,Object o2) 71 { 72 Student s1 = (Student)o1; 73 Student s2 = (Student)o2; 74 75 int num = s1.getName().compareTo(s2.getName()); 76 //当name相同时,再判断age 77 if(num==0) 78 { 79 return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge())); 80 } 81 return num; 82 } 83 }
十、Map接口
Map存储键值对。同时要保证键的唯一性。当数据之间存在这映射关系时,就应该先想通过Map来实现。
Map与Collection的区别:
1、Map存储的是键值对,是双列。Collection中是单列。
2、Map存储元素使用put方法。Collection使用add方法。
3、Map集合没有直接取出元素的方法,而是先转成Set集合,在通过迭代获取元素。
4、Map集合中键要保证键值唯一性。Collection中只有Set中有元素唯一性。
常用方法:
1、添加
put(K key, V value):返回这个键对应的原来的那个值。当存入一个新的键值时返回null,当存入一个已有键和不同的值时,新值会替换原来的值。返回原来的值
putAll(Map extends K,? extends V> m): 从指定映射中将所有映射关系复制到此映射中。
2、删除
clear() :从此映射中移除所有映射关系。
remove(Object key):如果存在一个键的映射关系,则将其从此映射中移除。
3、判断
containsValue(Object value):如果此映射将一个或多个键映射到指定值,则返回true。
containsKey(Object key) :如果此映射包含指定键的映射关系,则返回true。
isEmpty() :如果此映射未包含键-值映射关系,则返回true。
4、获取
get(Object key) :返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回null。
size() :返回此映射中的键-值映射关系数。
values() :返回此映射中包含的值的Collection视图
因为Map中无迭代器,所以如果要遍历,需先转换成Set:
keySet():返回此映射中包含的键的Set视图。
entrySet():返回此映射中包含的映射关系的Set视图。
十一、HashMap、TreeSet类
区别:HashMap通过hashcode对其内容进行快速查找,排序不固定。而TreeMap中所有的元素都保持着某种固定的顺序。
HashMap单键简单遍历:
1 mport java.util.HashMap; 2 import java.util.Map; 3 import java.util.Set; 4 5 public class HashMapTest { 6 7 public static void main(String[] args) { 8 Mapmap = new HashMap (); 9 map.put("001", "小明"); 10 map.put("002", "小天"); 11 map.put("003", "小强"); 12 13 //获取所有的键 14 Set set = map.keySet(); 15 for(String key : set) 16 { 17 String value = map.get(key); 18 System.out.println(key+":"+value); 19 } 20 } 21 22 }
HashMap键-值遍历:
1 import java.util.HashMap; 2 import java.util.Map; 3 import java.util.Set; 4 5 public class HashMapTest { 6 7 public static void main(String[] args) { 8 Mapmap = new HashMap (); 9 map.put("001", "小明"); 10 map.put("002", "小天"); 11 map.put("003", "小强"); 12 13 //获取所有的键 14 Set > set = map.entrySet(); 15 for(Map.Entry me : set) 16 { 17 String id = me.getKey(); 18 String name = me.getValue(); 19 System.out.println(id+":"+name); 20 } 21 } 22 23 }
十二、Collections和Arrays类
两者区别:
Collections:集合框架的工具类。里面定义的都是对集合操作的一系列静态方法。
Arrays:数组的工具类。里面定义的都是对数组操作静态方法。
Collection和Collections 有什么区别?
Collection 是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。它有两个常用的子接口,List:对元素都有定义索引。有序的。可以含重复元素。Set:不含重复元素。无序。
Collections 是集合框架中的一个工具类。该类中的方法都是静态的。提供的方法中有可以对list集合进行排序,二分查找等方法。通常常用的集合都是线程不安全的。因为要提高效率。如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。
Collections常用方法:
fill(List super T> list, T obj):使用指定元素替换指定列表中的所有元素。
max(Collection extends T> coll):根据元素的自然顺序,返回给定 collection 的最大元素。
max(Collection extends T> coll, Comparator super T> comp):根据指定比较器产生的顺序,返回给定 collection 的最大元素。
replaceAll(List
reverse(List> list):反转指定列表中元素的顺序。
reverseOrder():返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。
reverseOrder(Comparator
shuffle(List> list):使用默认随机源对指定列表进行置换。
sort(List
sort(List
swap(List> list, int i, int j):在指定列表的指定位置处交换元素。
synchronizedCollection(Collection
Arrays常用方法:
asList(T... a) ;返回一个受指定数组支持的固定大小的列表。
deepEquals(Object[] a1, Object[] a2): 如果两个指定数组彼此是深层相等 的,则返回true。
sort(byte[] a):对指定byte型数组按数字升序进行排序。
sort(byte[] a, int start, int end) :对指定byte型数组的指定范围按数字升序进行排序。
binarySearch(byte[] a, byte key) :使用二分搜索法来搜索指定的byte型数组,以获得指定的值。
binarySearch(byte[] a,int start,int end,byte key) :使用二分搜索法来搜索指定的byte型数组的指定范围,以获得指定的值。
toString(boolean[] a) :返回指定数组内容的字符串表示形式。
copyOfRange(byte[] bytes, int start, int end): 将指定数组的指定范围复制到一个新数组。
fill(boolean[] a, boolean val):将指定的 boolean 值分配给指定boolean型数组的每个元素。
fill(boolean[] a, int start, int end, boolean val) :将指定的boolean值分配给指定boolean型数组指定范围中的每个元素。
Arrays特殊方法:
asList(T... a):将数组变成list集合。
这样做的好处就是可以使用集合的思想和方法来操作数组中的元素。将数组变成集合后,不可以使用集合的增删方法。因为数组的长度是固定的。如果增删。会发生 UnsupportedOperationException,变成集合后可以使用的方法有:
contains(Object o):如果列表包含指定的元素,则返回true。
get(int index):返回列表中指定位置的元素。
indexOf(Object o):返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回-1。
subList(int fromIndex, int toIndex):返回列表中指定的范围之间的部分视图,含头不含尾。
注意:
如果数组中的元素都是对象。那么变成集合时,数组中的元素就直接转成集合中的元素。
如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。