集合框架 List Set Map
java中集合框架:
数组
链表:由节点组成
删除 添加操作 查找操作
链表快 链表慢
数组满 数组快
队列: 先进先出
栈: 先进后出
接口: Collection(List set) Map
List:存储的数据: 可以存储重复的数据 有序的 (和数组很像)
Set: 存储的数据: 不可以存储重复的数据 无序的
Map: key-value
集合框架: 不仅仅知道如何使用 还要知道底层的实现
集合: 只能存储引用数据类型
1.List接口
ArrayList 实现类: API
底层: 用数组来维护的
构造方法:
ArrayList list=new ArrayList(); 这样创建的初始容量默认只有10个
常用方法:
add() 将指定的元素添加到列表尾部
addAll() 将列表的元素添加到指定列表
clear() 清空列表里的所有元素
contian() 看列表是否包含指定元素 返回boolean
indexof() 返回列表中首次出现此元素的索引 没有就返回-1
lastindexof() 返回此列表中改元素最后一次出现的索引 没有就返回-1
isEmpty() 判断列表是否为空 返回值boolean
remove() 删除指定索引的元素
set() 用指定的元素替换指定索引的元素
toArray() 返回包含自列表中所有元素的数组
迭代器 设计模式 :
Iterator iterator=list.iterator(); while(iterator.hasNext()){ Object value=iterator.next();//获得下一个数据 System.out.println(value); }
为什么要使用迭代器呢?
1、迭代器可以提供统一的迭代方式。
2、迭代器也可以在对客户端透明的情况下,提供各种不同的迭代方式。
3、迭代器提供一种快速失败机制,防止多线程下迭代的不安全操作。
什么是快速失败机制:
modCount 记录修改此列表的次数 我们知道的是ArrayList是线程不安全的,如果在使用迭代器的过程中有其他的线程修改了List就会
抛出ConcurrentModificationException这就是Fail-Fast机制。
那么快速失败究竟是个什么意思呢?
在ArrayList类创建迭代器之后,除非通过迭代器自身remove或add对列表结构进行修改,否则在其他
线程中以任何形式对列表进行修改,迭代器马上会抛出异常,快速失败。
对于Collectin 接口下面的所有实现类都可以使用迭代器
面试题ArrayList和Vector的区别?
vector 是线程安全的
ArrayList 是线程不安全的
ArrayList存在线程安全问题 在一些老的系统里还会用Vector
但是大环境下是线程不安全的 如果要让ArrayList变为线程安全的
可以使用Collection.synchronizedList(new ArrayList());
LinkedList:
底层实现: 链表
2.Set:
List:存储的数据是有序的 允许出现重复的对象
Set: 存储的数据是无序的 不允许出现重复的对象
为什么不允许出现重复的对象?
会用equals()方法进行比较
HashSet底层: HashMap 实现 创建的初始容量位16
HashMap 底层是哈希表实现的
储存对象要结合 hashcode()和equals()实现 即在加入的对象中要重写hashcode()和equals()方法
hashcode(): 返回一个数值 可以理解为定位到数组的某一个索引上
equals(): 比较属性值是否相同
哈希表: 数组加链表实现 数组里面存储的链表
底层实现过程:
1.首先通过 hashcode()方法 计算出一个值 对应到数组的索引
2.equals(): 与当前数组索引下面的链表中的每一个对象进行比较
如果返回值为:false 那么就表明链表中节点对象与添加进去的对象不是同一个
如果返回值为:true 表明链表上面有与添加进去对象相同的对象
TreeSet
集合中存储的是对象。
数组中既能存储对象也能存储基本数据类型
TreeSet中添加简单的类型能自动排序 比如 set.add(1);
TreeSet添加的是复杂对象时
1.添加的对象 要实现Comparable接口
public class Person implements Comparable{ private int age; private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person(int age, String name) { this.age = age; this.name = name; } @Override public String toString() { return "Person [age=" + age + ", name=" + name + "]"; } @Override public int compareTo(Object o) { // TODO Auto-generated method stub return 1; }
2.写一个比较器 实现Comparator接口 匿名内部类
public void f1() { Comparator comparator=new Comparator() { @Override //1位升序 -1为降序 public int compare(Object o1, Object o2) { // TODO Auto-generated method stub Person p1=(Person) o1; Person p2=(Person) o2; if(p1.getAge()>p2.getAge()){ return 1;//降序 }else if(p1.getAge()<p2.getAge()){ return -1; } return 0; } }; TreeSet set=new TreeSet(comparator); Person p1=new Person(10,"张三"); Person p2=new Person(10,"张三"); Person p3=new Person(12,"张三"); set.add(p1); set.add(p2); set.add(p3); for (Object object : set) { System.out.println(object); } }
3.Map
HashTable HashMap Properties TreeMap
Map用于存储什么样的数据?
key--value的数据
HashMap: HashSet的底层是HashMap HashMap的底层是哈希表
Hashmap的遍历
1.把key值封装到set集合中 然后用迭代器或者foreach遍历
public void f1(){ HashMap map=new HashMap(); map.put("0571","杭州"); map.put("0572","济南"); Set keys=map.keySet(); for (Object key : keys) { Object value=map.get(key); System.out.println(value); } } public void f2(){ HashMap map=new HashMap(); map.put("0571","杭州"); map.put("0572","济南"); Set keys = map.keySet();//key值封装到Set集合中 Iterator iterator = keys.iterator(); while(iterator.hasNext()){ //key Object key = iterator.next(); Object value = map.get(key); System.out.println(key+"="+value); } }
2.将key和value 封装到set集合里面
public void f3(){ HashMap map=new HashMap(); map.put("0571","杭州"); map.put("0572","济南"); Set<Map.Entry<String,String>> entrySet=map.entrySet(); for (Entry<String, String> entry : entrySet) { String key=entry.getKey(); String value=entry.getValue(); System.out.println(key+"="+value); } }