java学习——java基础(五)之集合类
2017-08-20 02:05
411 查看
写在前面:周六的日子过的有些清闲,下午和大学同学去聚了聚,发现在不知不觉中已和他们有了一定的差距。得到了很多的收获,初入社会,要不断自我积累,不能让自己停步不前。或许若干年后,再翻看这篇博客会觉得自己也年轻过。对自己说,加油!!!
在Java中集合类有着重要的意义,保存临时数据、管理对象、泛型、Web框架等,很多都大量用到了集合类。同时,在一般的面试中,集合类也是关注的焦点。因此,今天我们来复习下集合类的相关知识。
那么,什么时候选择什么样的集合类呢?
使用集合类时注意事项
Set和List是由Collection派生的两个接口。
构造方法:
所有实现Collection接口的类都必须提供两个标准的构造函数:
(1)无参数的构造函数用于创建一个共的Collection。
(2)有一个Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。
查看集合元素:
若要检查Collection中的元素,可以使用foreach进行遍历,也可以使用迭代器,Collection支持iterator()方法,通过该方法可以访问Collection中的每一个元素。具体如下:
Collection接口中共性方法:
增加:
add() 将指定对象存储到容器中,add 方法的参数类型是Object 便于接收任意对象
addAll() 将指定集合中的元素添加到调用该方法和集合中
删除:
remove() 将指定的对象从集合中删除
removeAll() 将指定集合中的元素删除
修改:
clear() 清空集合中的所有元素
判断:
isEmpty() 判断集合是否为空
contains() 判断集合何中是否包含指定对象
containsAll() 判断集合中是否包含指定集合,使用equals()判断两个对象是否相等
获取:
int size() 返回集合容器的大小
转成数组:
toArray() 集合转换数组
实现List接口的常用类有LinkedList、ArrayList、Vector和Stack。
List特有的方法:
增加
void add(int index, E element) //指定位置添加元素
boolean addAll(int index, Collection c) //指定位置添加集合
删除
E remove(int index) //删除指定位置元素
修改
E set(int index, E element) //返回的是需要替换的集合中的元素
查找:
E get(int index) //注意: IndexOutOfBoundsException
int indexOf(Object o) // 找不到返回-1
lastIndexOf(Object o)
求子集合
List<E> subList(int fromIndex, int toIndex) //不包含toIndex
数组为什么是查询快?因为数组的内存空间地址是连续的。
原理:ArrayList底层维护了一个Object[] 用于存储对象,默认数组的长度是10。可以通过 new ArrayList(20)显式的指定用于存储对象的数组的长度。当默认的或者指定的容量不够存储对象的时候,容量自动增长为原来的容量的1.5倍。
由于链表实现增加时只要让前一个元素记住自己就可以,删除时让前一个元素记住后一个元素,后一个元素记住前一个元素。这样的增删效率较高。但查询时需要一个一个的遍历, 所以效率较低。
由于LinkedList提供的额外的方法,这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。额外的方法如下:
增删改查:
addFirst(E e),addLast(E e),getFirst(),getLast(),removeFirst(),removeLast()
如果集合中没有元素,获取或者删除元素抛:NoSuchElementException
栈:
push()
pop()
队列(双端队列):
offer()
poll()
返回逆序的迭代器对象:
descendingIterator() 返回逆序的迭代器对象
因为Vector是同步的,当一个iterator被创建而且这在被使用,另一个线程改变了Vector状态,这时调用iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。
Vector特有的方法:
void addElement(E obj) //在集合末尾添加元素
E elementAt( int index) //返回指定角标的元素
Enumeration elements() //返回集合中的所有元素,封装到Enumeration对象中
Enumeration 接口:
boolean hasMoreElements()//测试此枚举是否包含更多的元素。
E nextElement() //如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。
示例:
Stack提供了5个额外的方法使得Vector得以被当做堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,serach方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。
(1) ArrayList 是采用动态数组来存储元素的,它允许直接用下标号来直接查找对应的元素。但是,但是插入元素要涉及数组元素移动及内存的操作。总结:查找速度快,插入操作慢。
(2) LinkedList 是采用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
Iterator iterator() 返回该集合的迭代器对象。
Iterator接口定义的方法
Iterator是集合的迭代器接口类,定义了常见的迭代方法
boolean hasNext() //判断集合中是否有元素,如果有元素可以迭代,就返回true。
E next() //返回迭代的下一个元素,注意: 如果没有下一个元素时,调用next元素会抛出NoSuchElementException
void remove() //从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)。
示例:
List特有的ListIterator
ListIterator是List专属的迭代器。方法如下:
add(E e) //将指定的元素插入列表(可选操作)。该元素直接插入到 next 返回的下一个元素的前面(如果有)
void set(E o) //用指定元素替换 next 或 previous 返回的最后一个元素
hasPrevious() //逆向遍历列表,列表迭代器有多个元素,则返回 true。
previous() //返回列表中的前一个元素。
Iterator在迭代时,只能对元素进行获取(next())和删除(remove())的操作。对于 Iterator 的子接口ListIterator 在迭代list 集合时,还可以对元素进行添加(add(obj)),修改set(obj)的操作。
如果想要让两个不同的Person对象视为相等的,就必须覆盖Object继下来的hashCode方法和equals方法,因为Object hashCode方法返回的是该对象的内存地址,所以必须重写hashCode方法,才能保证两个不同的对象具有相同的hashCode,同时也需要两个不同对象比较equals方法会返回true。
所以重载equals方法同时也要重载hashCode,具体示例如下:
问题:为什么使用TreeSet存入字符串,字符串默认输出是按升序排列的?
因为字符串实现了一个接口,叫做Comparable接口。字符串重写了该接口的compareTo方法,所以String对象具备了比较性。那么同样道理,自定义元素(例如Person类、Book类)想要存入TreeSet集合,就需要实现该接口,也就是要让自定义对象具备比较性。存入TreeSet集合中的元素要具备比较性。
TreeSet如何保证元素的唯一性?
通过compareTo或者compare方法中的来保证元素的唯一性。
添加的元素必须要实现Comparable接口。当compareTo()函数返回值为0时,说明两个对象相等,此时该对象不会添加进来。
TreeSet集合排序的两种方式:
----| Comparable(接口)
compareTo(Object o) //元素自身具备比较性
----| Comparator(接口)
compare( Object o1, Object o2 )//给容器传入比较器
当Comparable比较方式,及Comparator比较方式同时存在,以Comparator比较方式为主。
两种方式的示例如下:
和Collection相比,区别如下:
(1) Map存储的是键值对
(2) Map存储元素使用put方法,Collection使用add方法
(3) Map集合没有直接取出元素的方法,而是先转成Set集合,在通过迭代获取元素
(4) Map集合中键要保证唯一性
(5) Collection是单列集合, Map 是双列集合。
(6) Map一次存一对元素, Collection 一次存一个。Map 的键不能重复,保证唯一。
(7) Map 一次存入一对元素,是以键值对的形式存在,键与值存在映射关系,一定要保证键的唯一性。
常用方法有:
添加:
V put(K key, V value) //可以相同的key值,但是添加的value值会覆盖前面的,返回值是前一个,如果没有就返回null。
putAll(Map<? extends K,? extends V> m) //从指定映射中将所有映射关系复制到此映射中(可选操作)。
删除
remove() //删除关联对象,指定key对象
clear() //清空集合对象
获取
value get(key) //可以用于判断键是否存在的情况。当指定的键不存在的时候,返回的是null。
判断:
boolean isEmpty() //长度为0返回true否则false
boolean containsKey(Object key) //判断集合中是否包含指定的key
boolean containsValue(Object value) //判断集合中是否包含指定的value
长度:
Int size()
底层是哈希表数据结构,线程是同步的,不可以存入null键,null值。
将HashMap视为集合时,其迭子操作时间开销和HahMap的容量成比例。因此,如果迭代操作的性能为先的话,不要将HashMap的初始化容量设的过高,或者load factor过低。
LinkedHashMap是HashMap的子类,该子类基于哈希表又融入了链表,提高了Map集合增删效率。
(2)values() 获取所有的值
(3)Map.Entry对象,推荐使用
(1)Set元素重复元素不能存入add方法返回false
(2)Map的重复健将覆盖旧键,将旧值返回。
2.看到array,就要想到角标。
看到link,就要想到first,last。
看到hash,就要想到hashCode,equals。
看到tree,就要想到两个接口:Comparable,Comparator。
在Java中集合类有着重要的意义,保存临时数据、管理对象、泛型、Web框架等,很多都大量用到了集合类。同时,在一般的面试中,集合类也是关注的焦点。因此,今天我们来复习下集合类的相关知识。
1.集合的分类
集合类主要目的是提供一组接口尽量简单而且相同并且尽量高效,以便于开发人员按照场景选用,而不是自己重复实现的类。容器按接口可以分为两大类:Collection和Map,如下图所示:那么,什么时候选择什么样的集合类呢?
Collection | 我们需要保存若干个对象的时候使用集合。 |
List | 如果我们需要保留存储顺序, 并且保留重复元素, 使用List. 如果查询较多, 那么使用ArrayList 如果存取较多, 那么使用LinkedList 如果需要线程安全, 那么使用Vector |
Set | 如果我们不需要保留存储顺序, 并且需要去掉重复元素, 使用Set.如果我们需要将元素排序, 那么使用TreeSet 如果我们不需要排序, 使用HashSet, HashSet比TreeSet效率高.如果我们需要保留存储顺序, 又要过滤重复元素, 那么使用LinkedHashSet |
Map | 如果需要存储键映射到值的对象,则使用Map 如果要求线程安全,则选择Hashtable 如果要求对键进行排序,则选择TreeMap |
类 | 类 | 类 | 说明 |
Collection | 单列集合 | ||
List | 有存储顺序, 可重复 | ||
ArrayList | 数组实现, 查找快, 增删慢 由于是数组实现, 在增和删的时候会牵扯到数组增容, 以及拷 贝元素. 所以慢。数组是可以直接按索引查找, 所以查找时较快 | ||
LinkedList | 链表实现, 增删快, 查找慢 由于链表实现, 增加时只要让前一个元素记住自己就可以, 删除 时让前一个元素记住后一个元素, 后一个元素记住前一个元素。 这样的增删效率较高但查询时需要一个一个的遍历, 所以效率较低 | ||
Vector | 和ArrayList原理相同, 但线程安全, 效率略低 和ArrayList实现方式相同, 但考虑了线程安全问题, 所以效率略低 | ||
Set | 无存储顺序, 不可重复 | ||
HashSet | 线程不安全,存取速度快。底层是以hash表实现的。 | ||
TreeSet | 红-黑树的数据结构,默认对元素进行自然排序(String)。如果在比较 的时候两个对象返回值为0,那么元素重复。 | ||
LinkedHashSet | 会保持插入顺序 | ||
Map | 键值对,将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。 | ||
HashMap | 底层是哈希表数据结构,线程是不同步的,可以存入null键,null值。 要保证键的唯一性,需要覆盖hashCode方法,和equals方法。 | ||
LinkedHashMap | 该子类基于哈希表又融入了链表。可以Map集合进行增删提高效率。 | ||
TreeMap | 底层是二叉树数据结构。可以对map集合中的键进行排序。需要使用Comparable或者 Comparator 进行比较排序。return 0,来判断键的唯一性。 | ||
HashTable | 底层是哈希表数据结构,线程是同步的,不可以存入null键,null值。效率较低,被HashMap 替代。 |
2.Collection接口
Collection接口并不是一个根接口,它的超级接口是Iterator,需要提供其遍历、移除元素(可选操作)的能力。Collection接口定义了基本的容器操作方法。Set和List是由Collection派生的两个接口。
构造方法:
所有实现Collection接口的类都必须提供两个标准的构造函数:
(1)无参数的构造函数用于创建一个共的Collection。
(2)有一个Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。
查看集合元素:
若要检查Collection中的元素,可以使用foreach进行遍历,也可以使用迭代器,Collection支持iterator()方法,通过该方法可以访问Collection中的每一个元素。具体如下:
Iterator it=collection.iterator(); while(it.hasNext()){ Object obj=it.next(); }
Collection接口中共性方法:
增加:
add() 将指定对象存储到容器中,add 方法的参数类型是Object 便于接收任意对象
addAll() 将指定集合中的元素添加到调用该方法和集合中
删除:
remove() 将指定的对象从集合中删除
removeAll() 将指定集合中的元素删除
修改:
clear() 清空集合中的所有元素
判断:
isEmpty() 判断集合是否为空
contains() 判断集合何中是否包含指定对象
containsAll() 判断集合中是否包含指定集合,使用equals()判断两个对象是否相等
获取:
int size() 返回集合容器的大小
转成数组:
toArray() 集合转换数组
3.List接口
List的元素有存储顺序,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引的位置来访问List中的元素,类似于Java数组。同时,List允许有相同的元素存在。除了具有Collection接口必备的的iterator()方法外,还提供了listIterator()方法,放回一个 ListIterator接口。实现List接口的常用类有LinkedList、ArrayList、Vector和Stack。
List特有的方法:
增加
void add(int index, E element) //指定位置添加元素
boolean addAll(int index, Collection c) //指定位置添加集合
删除
E remove(int index) //删除指定位置元素
修改
E set(int index, E element) //返回的是需要替换的集合中的元素
查找:
E get(int index) //注意: IndexOutOfBoundsException
int indexOf(Object o) // 找不到返回-1
lastIndexOf(Object o)
求子集合
List<E> subList(int fromIndex, int toIndex) //不包含toIndex
3.1 ArrayList
ArrayList实现了可变大小的数组,底层由数组实现,查找快, 增删慢。它允许所有元素,包括null。ArrayList没有同步。数组为什么是查询快?因为数组的内存空间地址是连续的。
原理:ArrayList底层维护了一个Object[] 用于存储对象,默认数组的长度是10。可以通过 new ArrayList(20)显式的指定用于存储对象的数组的长度。当默认的或者指定的容量不够存储对象的时候,容量自动增长为原来的容量的1.5倍。
3.2 LinkedList
LinkedList由链表实现, 增删快, 查找慢。允许null元素。由于链表实现增加时只要让前一个元素记住自己就可以,删除时让前一个元素记住后一个元素,后一个元素记住前一个元素。这样的增删效率较高。但查询时需要一个一个的遍历, 所以效率较低。
由于LinkedList提供的额外的方法,这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。额外的方法如下:
增删改查:
addFirst(E e),addLast(E e),getFirst(),getLast(),removeFirst(),removeLast()
如果集合中没有元素,获取或者删除元素抛:NoSuchElementException
栈:
push()
pop()
队列(双端队列):
offer()
poll()
返回逆序的迭代器对象:
descendingIterator() 返回逆序的迭代器对象
3.3 Vector
Vector描述的是一个线程安全的ArrayList。相对应的,ArrayList是单线程的所以效率高。因为Vector是同步的,当一个iterator被创建而且这在被使用,另一个线程改变了Vector状态,这时调用iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。
Vector特有的方法:
void addElement(E obj) //在集合末尾添加元素
E elementAt( int index) //返回指定角标的元素
Enumeration elements() //返回集合中的所有元素,封装到Enumeration对象中
Enumeration 接口:
boolean hasMoreElements()//测试此枚举是否包含更多的元素。
E nextElement() //如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。
示例:
public static void main(String[] args) { Vector v = new Vector(); v.addElement("aaa"); v.addElement("bbb"); v.addElement("ccc"); System.out.println( v ); System.out.println( v.elementAt(2) ); // ccc // 遍历Vector遍历 Enumeration ens = v.elements(); while ( ens.hasMoreElements() ) { System.out.println( ens.nextElement() ); } }
3.4 Stack
Stack继承自Vector,实现了一个后进先出的堆栈。Stack提供了5个额外的方法使得Vector得以被当做堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,serach方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。
3.5 ArrayList和LinkedList比较
ArrayList 和 LinkedList的存储查找的优缺点:(1) ArrayList 是采用动态数组来存储元素的,它允许直接用下标号来直接查找对应的元素。但是,但是插入元素要涉及数组元素移动及内存的操作。总结:查找速度快,插入操作慢。
(2) LinkedList 是采用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
3.6 迭代器
Collection的父接口,实现了Iterable的类就是可迭代的,并且支持增强for循环。Iterator iterator() 返回该集合的迭代器对象。
Iterator接口定义的方法
Iterator是集合的迭代器接口类,定义了常见的迭代方法
boolean hasNext() //判断集合中是否有元素,如果有元素可以迭代,就返回true。
E next() //返回迭代的下一个元素,注意: 如果没有下一个元素时,调用next元素会抛出NoSuchElementException
void remove() //从迭代器指向的集合中移除迭代器返回的最后一个元素(可选操作)。
示例:
Iterator it = list.iterator(); while (it.hasNext()) { String next = (String) it.next(); System.out.println(next); } for (Iterator it = list.iterator(); it.hasNext();) { //迭代器的next方法返回值类型是Object,所以要记得类型转换。 String next = (String) it.next(); System.out.println(next); }注意:在对集合进行迭代过程中,不允许出现迭代器以外的对元素的操作,因为这样会产生安全隐患,java会抛出异常并发修改异常(ConcurrentModificationException),普通迭代器只支持在迭代过程中的删除动作。
List特有的ListIterator
ListIterator是List专属的迭代器。方法如下:
add(E e) //将指定的元素插入列表(可选操作)。该元素直接插入到 next 返回的下一个元素的前面(如果有)
void set(E o) //用指定元素替换 next 或 previous 返回的最后一个元素
hasPrevious() //逆向遍历列表,列表迭代器有多个元素,则返回 true。
previous() //返回列表中的前一个元素。
Iterator在迭代时,只能对元素进行获取(next())和删除(remove())的操作。对于 Iterator 的子接口ListIterator 在迭代list 集合时,还可以对元素进行添加(add(obj)),修改set(obj)的操作。
4.Set接口
Set是一种不包含重复元素的Collection,该集合可以知道某元素是否已存在于集合中,用于存储无序(存入和取出的顺序不一定相同)元素。Set最多有一个null元素。如果想要让两个不同的Person对象视为相等的,就必须覆盖Object继下来的hashCode方法和equals方法,因为Object hashCode方法返回的是该对象的内存地址,所以必须重写hashCode方法,才能保证两个不同的对象具有相同的hashCode,同时也需要两个不同对象比较equals方法会返回true。
4.1 HashSet
调用原理:先判断hashCode 方法的值,如果相同才会去判断equals。如果不相同,是不会调用equals方法的。所以重载equals方法同时也要重载hashCode,具体示例如下:
@Override public int hashCode() { System.out.println("hashCode:" + this.name); return this.name.hashCode() + age * 37; } @Override public boolean equals(Object obj) { System.out.println(this + "---equals---" + obj); if (obj instanceof Person) { Person p = (Person) obj; return this.name.equals(p.name) && this.age == p.age; } else { return false; } }
4.2 TreeSet
TreeSet继承SortedSet接口,能够对集合中对象排序。默认排序方式是自然排序,但该方式只能对实现了Comparable接口的对象排序,java中对Integer、Byte、Double、Character、String等数值型和字符型对象都实现了该接口。问题:为什么使用TreeSet存入字符串,字符串默认输出是按升序排列的?
因为字符串实现了一个接口,叫做Comparable接口。字符串重写了该接口的compareTo方法,所以String对象具备了比较性。那么同样道理,自定义元素(例如Person类、Book类)想要存入TreeSet集合,就需要实现该接口,也就是要让自定义对象具备比较性。存入TreeSet集合中的元素要具备比较性。
TreeSet如何保证元素的唯一性?
通过compareTo或者compare方法中的来保证元素的唯一性。
添加的元素必须要实现Comparable接口。当compareTo()函数返回值为0时,说明两个对象相等,此时该对象不会添加进来。
TreeSet集合排序的两种方式:
----| Comparable(接口)
compareTo(Object o) //元素自身具备比较性
----| Comparator(接口)
compare( Object o1, Object o2 )//给容器传入比较器
当Comparable比较方式,及Comparator比较方式同时存在,以Comparator比较方式为主。
两种方式的示例如下:
public int compareTo(Object obj) { Person p = (Person) obj; System.out.println(this+" compareTo:"+p); if (this.age > p.age) { return 1; } if (this.age < p.age) { return -1; } return this.name.compareTo(p.name); } class MyComparator implements Comparator { public int compare(Object o1, Object o2) { Book b1 = (Book) o1; Book b2 = (Book) o2; System.out.println(b1+" comparator "+b2); if (b1.getPrice() > b2.getPrice()) { return 1; } if (b1.getPrice() < b2.getPrice()) { return -1; } return b1.getName().compareTo(b2.getName()); } }
5.Map接口
Map中的元素是两个对象,一个对象作为键,一个对象作为值。键不可以重复,但是值可以重复。和Collection相比,区别如下:
(1) Map存储的是键值对
(2) Map存储元素使用put方法,Collection使用add方法
(3) Map集合没有直接取出元素的方法,而是先转成Set集合,在通过迭代获取元素
(4) Map集合中键要保证唯一性
(5) Collection是单列集合, Map 是双列集合。
(6) Map一次存一对元素, Collection 一次存一个。Map 的键不能重复,保证唯一。
(7) Map 一次存入一对元素,是以键值对的形式存在,键与值存在映射关系,一定要保证键的唯一性。
常用方法有:
添加:
V put(K key, V value) //可以相同的key值,但是添加的value值会覆盖前面的,返回值是前一个,如果没有就返回null。
putAll(Map<? extends K,? extends V> m) //从指定映射中将所有映射关系复制到此映射中(可选操作)。
删除
remove() //删除关联对象,指定key对象
clear() //清空集合对象
获取
value get(key) //可以用于判断键是否存在的情况。当指定的键不存在的时候,返回的是null。
判断:
boolean isEmpty() //长度为0返回true否则false
boolean containsKey(Object key) //判断集合中是否包含指定的key
boolean containsValue(Object value) //判断集合中是否包含指定的value
长度:
Int size()
5.1 HashTable
HashTable继承Map接口,实现了一个key--value映射的哈希表。任何非空的对象都可作为key或者value。HashTable通过initial caoacity和load factor两个参数调整性能。通常缺省的load factor 0.75较好地实现了时间和空间的均衡。底层是哈希表数据结构,线程是同步的,不可以存入null键,null值。
5.2 HashMap
HashMap底层实现是哈希表数据结构,与HashTable不同之处在于,线程是不同步的,可以存入null键,null值。要保证键的唯一性,需要覆盖hashCode方法,和equals方法。将HashMap视为集合时,其迭子操作时间开销和HahMap的容量成比例。因此,如果迭代操作的性能为先的话,不要将HashMap的初始化容量设的过高,或者load factor过低。
LinkedHashMap是HashMap的子类,该子类基于哈希表又融入了链表,提高了Map集合增删效率。
5.3 TreeMap
底层是二叉树数据结构。可以对map集合中的键进行排序,需要使用Comparable或者Comparator 进行比较排序。通过返回值是否为0来判断键的唯一性。5.4 遍历Map的方式
(1)将map集合中所有的键取出存入set集合。Set<K> keySet(); //返回所有的key对象的Set集合,再通过get方法获取键对应的值。 Set<Integer> ks = map.keySet(); Iterator<Integer> it = ks.iterator(); while (it.hasNext()) { Integer key = it.next(); String value = map.get(key); System.out.println("key=" + key + " value=" + value); }
(2)values() 获取所有的值
Collection<V> values(); //不能获取到key对象 Collection<String> vs = map.values(); Iterator<String> it = vs.iterator(); while (it.hasNext()) { String value = it.next(); System.out.println(" value=" + value); }
(3)Map.Entry对象,推荐使用
Set<Map.Entry<k,v>> entrySet() //将map集合中的键值映射关系打包成一个对象 //Map.Entry对象通过Map.Entry 对象的getKey,getValue获取其键和值。 //返回的Map.Entry对象的Set集合 Map.Entry包含了key和value对象 Set<Map.Entry<Integer, String>> es = map.entrySet(); Iterator<Map.Entry<Integer, String>> it = es.iterator(); while (it.hasNext()) { // 返回的是封装了key和value对象的Map.Entry对象 Map.Entry<Integer, String> en = it.next(); // 获取Map.Entry对象中封装的key和value对象 Integer key = en.getKey(); String value = en.getValue(); System.out.println("key=" + key + " value=" + value); }
6.总结
1.Set的元素不可重复,Map的键不可重复,如果存入重复元素如何处理:(1)Set元素重复元素不能存入add方法返回false
(2)Map的重复健将覆盖旧键,将旧值返回。
2.看到array,就要想到角标。
看到link,就要想到first,last。
看到hash,就要想到hashCode,equals。
看到tree,就要想到两个接口:Comparable,Comparator。
相关文章推荐
- Java集合类框架学习 1 —— 概述与基础
- 黑马程序员 Java基础学习笔记 集合类
- javaee学习日记之java基础之集合类
- 黑马程序员—13—java基础:有关集合类的学习笔记和心得体会
- Java学习备忘录(二)基础语法和数组(原创)
- Java基础学习
- Java IO学习基础之读写文本文件
- java基础知识学习
- Java基础学习1
- Java IO学习基础之读写文本文件
- Java2核心技术第七版的学习笔记(三) Fundamental Programming Structures in Java(Java语言的基础)(二)
- Java IO学习基础之读写文本文件
- java学习笔记,关于java的一些基础知识,适用于初学者,第一节
- Java2核心技术第七版的学习笔记(三) Fundamental Programming Structures in Java(Java语言的基础)(三)
- Java2核心技术第七版的学习笔记(三) Fundamental Programming Structures in Java(Java语言的基础)(一)
- java基础学习---java对象序列化基础知识
- Java IO学习基础之读写文本文件
- 安全的基础----学习java安全之前的准备
- Java IO学习基础之读写文本文件
- java基础学习