java学习之集合框架
2015-05-23 23:26
309 查看
集合类的由来:
对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定,就使用集合容器进行存储。
集合的特点:
1、用于存储对象的容器。
2、集合的长度是可变的。
3、集合中不可以存储基本数据类型值。
集合容器因为内部的数据结构不同,有多种具体的容器,不断的向上抽取,就形成了集合框架。
集合框架图:
框架的顶层Collection接口:
Collection的常见方法:
1、添加
boolean add(Object obj);
boolean addAll(Collection coll);
2、删除
boolean remove(Object obj); 会改变集合长度
boolean removeAll(Collection coll);
void clear();
3、判断
boolean contains(Object obj);
boolean containsAll(Collection coll);
boolean isEmpty(); 判断集合中是否有元素
4、获取
int size();
Iterator iterator(); 取出元素的方式:迭代器的对象必须依赖于具体容器,因为每一个容器的数据结构不同,
所以该迭代器对象是在容器中进行内部实现的。
对于使用容器者而言,具体的实现不重要,只要通过容器过去到该实现的迭代器的对象即可,也就是iterator方法。
Iterator接口就是对所有的Collection容器进行元素取出的公共接口。
5、其他
boolean retainAll(Collection coll); 取交集
Object[] toArray(); 将集合转成数组。
Collection
---List:有序(存入和取出的顺序一致),元素都有索引,元素可以重复。
---Set:元素不能重复,无序。
List:特有的常见方法,有一个共性特点就是都可以操作角标。
1、添加
boolean add(E e);
void add(int index, E element);
2、删除
Object remove(int index);
3、修改:
Object set(int index, E element)
4、获取:
Object get(int index);
int indexOf(object);
int lastIndexOf(object);
List subList(int fromIndex, int toIndex);
list集合是可以完成对元素的增删改查
List:
---Vector:内部是数组数据结构,是同步的(线程是安全的)。增删,查询都很慢。
---ArrayList:内部是数组数据结构,是不同步的。替代了Vector。查询的速度快。
---LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。
LinkedList:
addFirst();
addLast();
JDK1.6后
offerFirst();
offerLast();
getFirst();//获取但不移除,如果链表为空,抛出NoSuchElementException
getLast();
JDK1.6后
peekFirst();//获取但不移除,如果链表为空,返回null
peekLast();
removeFirst();获取并移除,如果链表为空,抛出NoSuchElementException
removeLast();
JKD1.6后:
pollFirst();//获取并移除,如果链表为空,返回null
pollLast();
LinkedList练习代码:
Set:元素不可以重复,是无序的。
Set接口中的方法和Collection一致
|---HashSet:内部数据结构是哈希表,是不同步的。
如何保证该集合的元素唯一性呢?
是通过对象的hashCode和equals方法来完成对象唯一性的。
如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。
如果为true,视为相同元素,不存入。如果为false,那么视为不同元素,就进行存储。
|---TreeSet:可以对Set集合中的元素进行排序,是不同步的。
判断元素唯一性的方式:就是根据比较方法的返回结果是否是0,如果是0就是相同元素,不存储。
TreeSet对元素进行排序的方式一:
让元素自身具备比较功能,元素需要实现Comparable接口,覆盖compareTo方法。
如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序。怎么办?
可以使用TreeSet集合的排序方式二:
让集合自身具备比较功能,定义一个类实现Comparator(比较器)接口,覆盖compare方法。
将该类对象作为参数传递给TreeSet集合的构造函数。
Set集合输出顺序和存入的顺序不一致。第五行和第八行都把字符串"xixi"添加到集合中,但是Set集合不能
存放相同的元素,所以没有添加进去。
哈希表确定元素是否相同:
1、判断的是两个元素的哈希值是否相同。
如果相同,再判断两个对象的内容是否相同。
2、判断哈希值相同,其实判断的是对象的hashCode方法。判断内容相同,用的是equals方法。
注意:如果哈希值不同,是不需要判断equals的。
用哈希表存储自定义对象时,一般需要覆盖其父类Object中的hashCode方法和equals方法,构造自己的判断是否相同的方式。
如果哈希表要保证存入和输出有序,那可以使用HashSet的子类LinkedHashSet
Map:一次添加一对元素。Collection一次添加一个元素
Map也称为双列集合,Collection集合称为单列集合。
其实Map集合中存储的就是键值对,必须保证键的唯一性。
常用方法:
1、添加:
value put(key, value);返回前一个和key关联的值,如果没有返回null
2、删除:
void clear();清空Map集合
value remove (key);根据指定的key删除这个键值对
3、判断:
boolean containsKey(key);
boolean containsValue(value);
boolean isEmpty();
4、获取:
value get(key);通过键获取值,如果没有该键,返回null。可以通过返回null,来判断是否包含指定键。
int size();获取键值对的个数。
获取map中的元素方式一:
获取map中的元素方式二:
获取map中的元素方式三:
集合的一些技巧:
需要唯一吗?
需要:Set
需要指定顺序吗?
需要:TreeSet
不需要:HashSet
但是想要一个和存储一直的顺序(有序):LinkedHashSet
不需要:List
需要频繁增删吗?
需要:LinkedList
不需要:ArrayList
如何记住每一个容器的结构和所属体系?看容器名字
List:
|---ArrayList
|---LinkedList
Set:
|---HashSet
|---TreeSet
后缀名就是该集合所属的体系,前缀名就是该集合的数据结构。
看到array就要想到数组,就要想到查询快,有下标
看到link就要想到链表,就要想到增删快,就要想到add get remove + frist last的方法
看到hash就要想到哈希表,就要想到唯一性,就要想到元素需要覆盖hashCode方法和equals方法
看到tree就要想到二叉树,就要想到排序,就要想到两个接口Comparable,Comparator接口
而且通常这些常用的集合容器都是不同步的。
对象用于封装特有数据,对象多了需要存储,如果对象的个数不确定,就使用集合容器进行存储。
集合的特点:
1、用于存储对象的容器。
2、集合的长度是可变的。
3、集合中不可以存储基本数据类型值。
集合容器因为内部的数据结构不同,有多种具体的容器,不断的向上抽取,就形成了集合框架。
集合框架图:
框架的顶层Collection接口:
Collection的常见方法:
1、添加
boolean add(Object obj);
boolean addAll(Collection coll);
2、删除
boolean remove(Object obj); 会改变集合长度
boolean removeAll(Collection coll);
void clear();
3、判断
boolean contains(Object obj);
boolean containsAll(Collection coll);
boolean isEmpty(); 判断集合中是否有元素
4、获取
int size();
Iterator iterator(); 取出元素的方式:迭代器的对象必须依赖于具体容器,因为每一个容器的数据结构不同,
所以该迭代器对象是在容器中进行内部实现的。
对于使用容器者而言,具体的实现不重要,只要通过容器过去到该实现的迭代器的对象即可,也就是iterator方法。
Iterator接口就是对所有的Collection容器进行元素取出的公共接口。
5、其他
boolean retainAll(Collection coll); 取交集
Object[] toArray(); 将集合转成数组。
Collection
---List:有序(存入和取出的顺序一致),元素都有索引,元素可以重复。
---Set:元素不能重复,无序。
List:特有的常见方法,有一个共性特点就是都可以操作角标。
1、添加
boolean add(E e);
void add(int index, E element);
2、删除
Object remove(int index);
3、修改:
Object set(int index, E element)
4、获取:
Object get(int index);
int indexOf(object);
int lastIndexOf(object);
List subList(int fromIndex, int toIndex);
public static void showMethod1(List list) { //添加元素 list.add("asd1"); list.add("asd2"); list.add("asd3"); System.out.println(list);//[asd1, asd2, asd3] //插入元素 list.add(1, "asd4"); System.out.println(list);//[asd1, asd4, asd2, asd3] //删除元素 System.out.println("remove = " + list.remove(0));//remove = asd1 System.out.println(list);//[asd4, asd2, asd3] //修改元素 System.out.println("set = " + list.set(1, "asd5"));//set = asd2 返回被修改的那个 System.out.println(list);//[asd4, asd5, asd3] //获取元素 System.out.println("get = " + list.get(0));//get = asd4 //获取子列表 System.out.println("subList = " + list.subList(1, 2));//subList = [asd5] }取出元素方法:
public static void showMethod2(List list) { list.add("asd1"); list.add("asd2"); list.add("asd3"); list.add("asd4"); Iterator it = list.iterator(); while(it.hasNext()) { System.out.println(it.next()); } //List特有的取出元素的方式之一 for(int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } }
list集合是可以完成对元素的增删改查
List:
---Vector:内部是数组数据结构,是同步的(线程是安全的)。增删,查询都很慢。
---ArrayList:内部是数组数据结构,是不同步的。替代了Vector。查询的速度快。
---LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。
LinkedList:
addFirst();
addLast();
JDK1.6后
offerFirst();
offerLast();
getFirst();//获取但不移除,如果链表为空,抛出NoSuchElementException
getLast();
JDK1.6后
peekFirst();//获取但不移除,如果链表为空,返回null
peekLast();
removeFirst();获取并移除,如果链表为空,抛出NoSuchElementException
removeLast();
JKD1.6后:
pollFirst();//获取并移除,如果链表为空,返回null
pollLast();
LinkedList练习代码:
public static void main(String[] args) { LinkedList link = new LinkedList(); //往链表头添加元素 link.addFirst("abc1"); link.addFirst("abc2"); link.addFirst("abc3"); link.addFirst("abc4"); Iterator it = link.iterator(); while(it.hasNext()) { System.out.println(it.next()); } System.out.println(link);//[abc4, abc3, abc2, abc1] System.out.println(link.getFirst());//abc4 取得链表头元素,但不删除 System.out.println(link.getLast());//abc1 取得链表尾元素,但不删除 System.out.println(link.removeFirst());//abc4 删除链表头元素,返回被删除的元素 System.out.println(link.removeFirst());//abc3 System.out.println(link);//[abc2, abc1] //利用removeFirst取得链表中的每个元素,但是结束后链表变为空 while(!link.isEmpty()) { System.out.println(link.removeFirst()); } System.out.println(link);//[] }
Set:元素不可以重复,是无序的。
Set接口中的方法和Collection一致
|---HashSet:内部数据结构是哈希表,是不同步的。
如何保证该集合的元素唯一性呢?
是通过对象的hashCode和equals方法来完成对象唯一性的。
如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。
如果为true,视为相同元素,不存入。如果为false,那么视为不同元素,就进行存储。
|---TreeSet:可以对Set集合中的元素进行排序,是不同步的。
判断元素唯一性的方式:就是根据比较方法的返回结果是否是0,如果是0就是相同元素,不存储。
TreeSet对元素进行排序的方式一:
让元素自身具备比较功能,元素需要实现Comparable接口,覆盖compareTo方法。
如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序。怎么办?
可以使用TreeSet集合的排序方式二:
让集合自身具备比较功能,定义一个类实现Comparator(比较器)接口,覆盖compare方法。
将该类对象作为参数传递给TreeSet集合的构造函数。
Set集合输出顺序和存入的顺序不一致。第五行和第八行都把字符串"xixi"添加到集合中,但是Set集合不能
存放相同的元素,所以没有添加进去。
public static void main(String[] args) { HashSet hs = new HashSet(); hs.add("haha"); hs.add("xixi"); hs.add("hehe"); hs.add("heihei"); hs.add("xixi"); Iterator it = hs.iterator(); while(it.hasNext()) { System.out.println(it.next()); } /*输出 * haha * heihei * xixi * hehe*/ }
哈希表确定元素是否相同:
1、判断的是两个元素的哈希值是否相同。
如果相同,再判断两个对象的内容是否相同。
2、判断哈希值相同,其实判断的是对象的hashCode方法。判断内容相同,用的是equals方法。
注意:如果哈希值不同,是不需要判断equals的。
用哈希表存储自定义对象时,一般需要覆盖其父类Object中的hashCode方法和equals方法,构造自己的判断是否相同的方式。
如果哈希表要保证存入和输出有序,那可以使用HashSet的子类LinkedHashSet
Map:一次添加一对元素。Collection一次添加一个元素
Map也称为双列集合,Collection集合称为单列集合。
其实Map集合中存储的就是键值对,必须保证键的唯一性。
常用方法:
1、添加:
value put(key, value);返回前一个和key关联的值,如果没有返回null
2、删除:
void clear();清空Map集合
value remove (key);根据指定的key删除这个键值对
3、判断:
boolean containsKey(key);
boolean containsValue(value);
boolean isEmpty();
4、获取:
value get(key);通过键获取值,如果没有该键,返回null。可以通过返回null,来判断是否包含指定键。
int size();获取键值对的个数。
public static void method1(Map<Integer, String> map) { //添加元素 System.out.println(map.put(8, "wangcai"));//null 没有原来值,返回null System.out.println(map.put(8, "xiaoqiang"));//wangcai 替换了原来的值,返回原来的值 map.put(2, "zhangsan"); map.put(5, "wangwu"); System.out.println(map);//{2=zhangsan, 5=wangwu, 8=xiaoqiang} //删除 System.out.println("remove:" + map.remove(2));//remove:zhangsan //判断 System.out.println("comtainskey:" + map.containsKey(5));//comtainskey:true //获取 System.out.println("get:" + map.get(8));//get:xiaoqiang }
获取map中的元素方式一:
private static void method2(Map<Integer, String> map) { map.put(8, "wangwu"); map.put(5, "zhangsan"); map.put(7, "xiaohong"); map.put(9, "zhaoming"); //取出map中的所有元素。 //原理:通过keySet方法获取map中所有的键所在的Set集合,再通过Set的迭代器 //获取到每一个键,再对每一个键获取其对于的值即可。 Set<Integer> keySet = map.keySet(); Iterator<Integer> it = keySet.iterator(); while(it.hasNext()) { Integer key = it.next(); System.out.println(map.get(key)); /*zhangsan xiaohong wangwu zhaoming*/ } }
获取map中的元素方式二:
private static void method3(Map<Integer, String> map) { /* * 通过Map转成Set就可以迭代,找到另一个方法entrySet * 该方法得到键和值的映射关系作为对象存储到了Set集合中, * 而这个映射关系的类型就是Map.Entry类型。 */ map.put(8, "wangwu"); map.put(5, "zhangsan"); map.put(7, "xiaohong"); map.put(9, "zhaoming"); Set<Map.Entry<Integer,String>> entrySet = map.entrySet(); Iterator<Map.Entry<Integer, String>> it = entrySet.iterator(); while (it.hasNext()) { Map.Entry<Integer, String> me = it.next(); Integer key = me.getKey(); String value = me.getValue(); System.out.println(key + " : " + value); } /* * 5 : zhangsan * 7 : xiaohong * 8 : wangwu * 9 : zhaoming */ }
获取map中的元素方式三:
private static void method4(Map<Integer, String> map) { map.put(8, "wangwu"); map.put(5, "zhangsan"); map.put(7, "xiaohong"); map.put(9, "zhaoming"); Collection<String> values = map.values(); Iterator<String> it = values.iterator(); while(it.hasNext()) { System.out.println(it.next()); } /*zhangsan xiaohong wangwu zhaoming*/ }
集合的一些技巧:
需要唯一吗?
需要:Set
需要指定顺序吗?
需要:TreeSet
不需要:HashSet
但是想要一个和存储一直的顺序(有序):LinkedHashSet
不需要:List
需要频繁增删吗?
需要:LinkedList
不需要:ArrayList
如何记住每一个容器的结构和所属体系?看容器名字
List:
|---ArrayList
|---LinkedList
Set:
|---HashSet
|---TreeSet
后缀名就是该集合所属的体系,前缀名就是该集合的数据结构。
看到array就要想到数组,就要想到查询快,有下标
看到link就要想到链表,就要想到增删快,就要想到add get remove + frist last的方法
看到hash就要想到哈希表,就要想到唯一性,就要想到元素需要覆盖hashCode方法和equals方法
看到tree就要想到二叉树,就要想到排序,就要想到两个接口Comparable,Comparator接口
而且通常这些常用的集合容器都是不同步的。
相关文章推荐
- java.util包的集合框架学习
- Java集合框架学习记录
- java学习之集合框架
- java学习笔记:集合框架之TreeSet
- 黑马程序员--java学习之集合框架
- 黑马程序员--Java学习日记8_集合框架
- 黑马程序员_Java学习日记8_集合框架1
- 黑马程序员_Java学习日记10_集合框架2
- java学习笔记-集合框架-黑马
- 黑马程序员_JAVA学习日记_JAVA中API:集合框架1(Collection,List,Set及其子类和迭代器的应用)
- 黑马程序员_JAVA学习日记_JAVA中API:集合框架2(Map集合及其子集合)
- Java学习札记20:Java程序员集合框架面试题
- java学习笔记:集合框架之TreeSet
- java 集合框架学习总结
- 【Java学习笔记】集合框架的学习
- Java学习笔记——JCF集合框架
- Java集合框架学习总结
- Java学习札记——集合框架一
- Java学习札记——集合框架二 Map
- 黑马程序员java学习日记——集合框架