????图片来源:菜鸟教程
【集合的理解和好处】
一、集合和数组
区别 | 集合 | 数组 |
长度 | 可变 | 固定 |
内容 | 只能是引用类型 | 基本类型和引用类型 |
元素内容 | 可以存储不同类型(但一般存储的也是同一类型) | 只能存同一种类型 |
【 Collection 接口】
一、Collection集合的方法:
remove方法:可以通过下标来删除,list.remove(1);但若是想要remove包装类对象的话,可以:list.remove(Interger.valueOf(1));
二、Collection接口遍历元素方式
- 使用Iterator(迭代器)快捷键:
itit
(1)Iterator对象称为迭代器,迭代器主要用于遍历 Collection集合中的元素
(2)所有实现了Collection接口的集合类都有一个 iterator() 方法,用以返回一个实现了 Iterator接口的对象,即返回一个迭代器。
(3)它仅用于遍历集合,本身并不存放对象。
迭代器的核心方法:
Object next():返回迭代器刚越过的元素的引用,返回值是 Object,需要强制转换成自己需要的类型
boolean hasNext():判断容器内是否还有可供访问的元素
void remove():删除迭代器刚越过的元素
Iterator iterator = list.iterator(); //首先获取Iterator对象
while(iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
} //遍历完,迭代器指向最后一个元素,这时使用remove方法会remove掉最后面的那个元素
//若希望迭代器重新指向开头,只需 iterator = list.iterator();
- 增强for循环:可以替代iterator迭代器,本质上是简化版的iterator,只能用于遍历集合或数组。
快捷键:I
或集合或数组名.for
for (Object o : list) { System.out.println(o); }
- 普通for循环:需要使用方法 size()和get()方法;
【 List 接口】
List集合:有序,支持索引,可重复的集合
List接口的三个典型实现:
(1)ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高
(2)LinkedList 底层数据结构是链表,查询慢,增删快,线程不安全,效率高
(3)Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低
它们的使用场景:
(1) 对于需要快速插入,删除元素,应该使用LinkedList。
(2) 对于需要快速随机访问元素,应该使用ArrayList。
(3) 对于“单线程环境” 或者 “多线程环境,但List仅仅只会被单个线程操作”,此时应该使用非同步的类(如ArrayList)。
对于“多线程环境,且List可能同时被多个线程操作”,此时,应该使用同步的类(如Vector)。
List接口常用方法:
【 Set 接口】
Set 接口:无序,不支持索引,不可重复的集合
Set 接口继承于 Collection 接口,主要的实现类:HashSet 和 TreeSet
(1)
(2)HashSet子类,LinkedHashSet
(3)TreeSet:
【 Map 接口】 Java8
一、概要
Map 接口中键和值一一映射. 可以通过键来获取值。
- Map中的 key 和 value 可以是任何引用类型的数据,会封装到 HashMap¥Node对象中;
- Map中的 key 不允许重复,原因和 HashSet一样;
- Map 中的 value可以重复;常用String类作为 Map 的 key;
- Map存放数据的 key-value 示意图,一对 k-v 是放在一个 HashMap¥Node中的。又因为 Node 实现了 Entry 接口,有些书上也说 一对k-v就是一个 Entry
在底层,它其实没有真正再重新拿一份数据,它只是为了你方便遍历这里的数据(k-v),它提供了一个Set,一个Collection,把k-v做成一个Entry对象,这些Entry对象再一起放在entrySet里面。所以只是简单的引用
Set keySet();
Collection values();
Set<Map.Entry<K, V>> entrySet(); - k-v 最后是存放在 一个内部类对象中:HashMap$Node node = newNode(hash, key, value, null);
- entrySet中,定义的类型是 Map.Entry,但实际上存放的还是 HashMap$Node:
这是因为: - 当把 HashMap$Node 对象存放到 entrySet就方便我们遍历,因为 Map.Entry提供了重要方法:
K getKey(); V getValue();
二、使用:
- 常用方法:
Map map = new HashMap(); //put map.put("hgj",null); map.put("zzy","hxy"); map.put("lzy",null); map.put("lcj","girl"); System.out.println("put 之后:" + map); //remove map.remove("hgj"); System.out.println("remove 之后:" + map); //get Object obj = map.get("lcj"); System.out.println("get:" + obj); //size System.out.println("size:" + map.size()); //isEmpty System.out.println("isEmpty:" + map.isEmpty()); //containsKey System.out.println("containsKey : " + map.containsKey("zzy")); //clear map.clear(); System.out.println("clear后:" + map);
- 三种遍历方式:
涉及的方法:
containsKey:查找键是否存在
KeySet:获取所有的键
values:获取所有的值
entrySet:获取所有关系 k-v
(1)keySet:// 两种方式 迭代器;增强for循环。 // Set是无序的,没有普通for循环 System.out.println("------------keySet----------"); Set set = map.keySet(); Iterator iterator = set.iterator(); while (iterator.hasNext()) { Object next = iterator.next(); System.out.println(next + "-" + map.get(next)); }
(2)values:// 也是两种方式,普通for循环不行,没有 get() 方法 System.out.println("-----------values-----------"); Collection values = map.values(); for (Object value : values) { System.out.println(value); }
(3)entrySet://同样是两种方式,迭代器和增强for循环 //(1) 需要使用到接口 Entry 提供的两个方法: // K getKey(); // V getValue(); //(2)还需要进行向下转型: // entrySet集合里面存放的对象实际上是 HashMap$Node // System.out.println(o.getClass());输出的是: // class java.util.HashMap$Node // 而且内部类Node实现了Map.Entry接口,所以向下转型成 Map.Entry, // 然后使用它提供的两个方法。 System.out.println("------------entrySet----------"); Set set1 = map.entrySet(); for (Object o : set1) { Map.Entry m = (Map.Entry) o; System.out.println(m.getKey() + "-" + m.getValue()); }
三、常用实现类及其特点
- Map接口的常用实现类:HashMap(使用频率最高)、Hashtable、Properties
(1)