集合与数组的区别
- 数组的长度是不可变化的,比如 声明长度是10的数组,不用的数组就浪费了超过10的个数,又放不下 ,为了解决数组的局限性,引入容器类的概念。 最常见的容器类就是ArrayList 只需要不断往容器里增加数据即可,不用担心会出现数组的边界问题。
collection接口
collection接口是LIst、Set、Queue接口的父接口,该接口的方法可以操作LIst、Set、Queue集合
- boolean add(Object o):用于向集合中添加一个元素
- boolean addAll(Collection c):用于把集合c中的所有元素都添加到指定集合中
- void clean():清空集合中的所有元素
- boolean contains(Object o):返回集合中是否包含指定元素
- boolean containsAll(Collection c):返回集合中是否包含集合c里的所有元素
- boolean isEmpty():返回集合是否为空
- boolean remove(Object o):删除集合中指定的元素,当集合中包含多个o时,只删除第一个符合添加的元素
- boolean removeAll(Collection c):删除集合c中包含的所有元素
- boolean retainAll(Collection c):和c集合取3交集
- int size():返回集合中元素的个数
- Object[] toArray():把集合转换成一个数组
- Iterator iterator():返回一个Iterator 对象用来遍历集合
Iterator 接口
Iterator 接口和collection接口、map接口不一样,其主要是为了遍历collection接口中的元素,它本身不能用来存放其它对象
Iterator 的几个方法:
- boolean hasNext():如果迭代的集合没有被遍历完返回true
- Object next():返回集合中的下一个元素
- void remove():删除集合里上一次next方法返回的元素
1.遍历集合的几个常用方法
foe循环遍历
List<Hero> heros = new ArrayList<Hero>();
// 放5个Hero进入容器
for (int i = 0; i < 5; i++) {
heros.add(new Hero("hero name " + i));
}
// 第一种遍历 for循环
System.out.println("--------for 循环-------");
for (int i = 0; i < heros.size(); i++) {
Hero h = heros.get(i);
System.out.println(h);
}
2.使用迭代器Iterator遍历集合中的元素
List<Hero> heros = new ArrayList<Hero>();
//放5个Hero进入容器
for (int i = 0; i < 5; i++) {
heros.add(new Hero("hero name " +i));
}
//第二种遍历,使用迭代器
System.out.println("--------使用while的iterator-------");
Iterator<Hero> it= heros.iterator();
//从最开始的位置判断"下一个"位置是否有数据
//如果有就通过next取出来,并且把指针向下移动
//直到"下一个"位置没有数据
while(it.hasNext()){
Hero h = it.next();
System.out.println(h);
}
//迭代器的for写法
System.out.println("--------使用for的iterator-------");
for (Iterator<Hero> iterator = heros.iterator(); iterator.hasNext();) {
Hero hero = (Hero) iterator.next();
System.out.println(hero);
}
3. 用增强型for循环
List<Hero> heros = new ArrayList<Hero>();
// 放5个Hero进入容器
for (int i = 0; i < 5; i++) {
heros.add(new Hero("hero name " + i));
}
// 第三种,增强型for循环
System.out.println("--------增强型for循环-------");
for (Hero h : heros) {
System.out.println(h);
}
Set接口
set的集合都是线程不安全的,如果有多个线程同时访问一个set集合,并有超过一个线程修改了该set就用使用Collections工具类的synchronizedSortedSet方法来包装该Set集合
HashSet集合
HashSet是Set接口的典型实现,HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能
HashSet的特点:
- 不能保证元素的排序顺序,元素的存储位置是由hashCode()算法得出
- HashSet不是同步的,如果多个线程同时访问一个HashSet,则必须通过代码来保证其同步
- 集合元素可以使NUll
HashSet判断集合的两个元素相等的标准是两个对象通过equals()方法比较相等并且两个对象的hashCode()方法返回值也相等,所以在重写equals()方法时必须也重写hashCode()方法
LinkedHashSet类(有序的)
LinkedHashSet是HashSet的子类,也是根据元素的hashCode值来决定元素的存储位置,但它同时又采用链表来维护元素的次序,这样使得LinkedHashSet会按元素的添加顺序来访问集合里的元素
List接口
List集合默认按照元素的顺序设置元素的索引,第一次添加索引为0,第二次添加索引为1
LIst接口的常用方法:
- Object get(int i):获取集合中的i个元素
- int indexOf(Object o):获取o所在的位置
- int lastIndexOf(Object o):返回对象o在list集合中最后一次出现的位置
- Object set(int index,Object element):将index处的元素替换成element对象,返回被替换的救元素
ListIterator迭代器
ListIterator接口继承了Iterator接口,并且提供了专门操作List的方法
- boolean hasPrevious():返回该迭代器关联的集合是否还有上一个元素
- Object previous():返回该迭代器的上一个元素
- void add(Object o):在指定位置插入一个元素
固定长度的List(Arrays.asList)
数组工具类Arrays,该工具类提供了asList(Object o)方法,该方法可以把一个数组或指定个数的对象转换成一个List集合,这个List集合既不是ArrayList实现类也不是Vector实现类,而是Arrays的内部类ArrayList的实例。程序只能遍历访问该集合的元素,不可增加和删除
LinkedList实现类
与ArrayList一样,LinkedList也实现了List接口,诸如add,remove,contains等等方法。除了实现了List接口外,LinkedList还实现了双向链表结构Deque,可以很方便的在头尾插入删除数据
LinkedList常用方法:
- offer():将元素加入队列的尾部
- push():将元素加入栈的顶部
- peekFirst():访问栈顶的元素
- peekLast():访问栈底的元素
- pop():删除栈顶的元素
- pollLast():删除队列的最后一个元素
ArrayList和LinkedList的区别
ArrayList 插入,删除数据慢
LinkedList, 插入,删除数据快
ArrayList是顺序结构,所以定位很快,指哪找哪。 就像电影院位置一样,有了电影票,一下就找到位置了。
LinkedList 是链表结构,就像手里的一串佛珠,要找出第99个佛珠,必须得一个一个的数过去,所以定位慢
ArrayList和HashSet的区别
ArrayList: 有顺序
HashSet: 无顺序
List中的数据可以重复
Set中的数据不能够重复
Map集合
map是一键值对(key,value)来保存数据,因此可以用于保存任何一个引用类型的数据,map的key很像set集合,key没有顺序,也不能重复;而value很像List集合,元素之间可以重复,每个元素都是根据索引来查找
常用方法:
- void clear():删除该map中的所有键值对
- boolean containsValue(Object value):查询map中是否包含value,有返回true
- boolean containsKey(Object key):查询map中是否包含key,有返回true
- Object get(Object key):返回指定key中对应的value
- boolean isEmpty():是否为空
- Object remove(Object key):删除指定key对应的键值对
- int size():返回键值对个数
- Set keySet():返回该Map中的所有key组成的set集合
- Collection values():返回该Map里所有value组成的Collection
- Object put(Object key,Object value):添加一个键值对
HashMap和Hashtable的区别
HashMap和Hashtable都实现了Map接口,都是键值对保存数据的方式
区别1:
HashMap可以存放 null,Hashtable不能存放null;HashMap可以使用null作为key和value,但是只有一个key允许为null,value允许多个为null;Hashtable不允许使用null作为key和value
区别2:
HashMap不是线程安全的类,Hashtable是线程安全的类;
建议尽量少用Hashtable,可以通过Collections工具类把HashMap变成线程安全的
HashMap和HashSet一样不能保证元素的顺序一样,它也不能保证键值对的顺序;
HashMap判断两个key是否相等的条件:
1.两个Key的通过equals()方法返回true
2.两个key的hashCode值相等
HashMap判断两个value是否相等的条件:
1.两个value的通过equals()方法返回true
与HashSet类似的是,如果使用可变对象作为HashMap、Hashtablede的key,并且程序修改了作为key的可变对象,程序就无法访问到被修改的key;
LinkedHashMap实现类
HashMap用来存放键值对时是无序的,你按顺序添加的键值对不会按顺序输出,LinkedHashMap则解决了这个问题,LinkedHashMap采用双向链表来维护键值对的次序,按顺序添加的键值对会按顺序输出
Collections操作集合的工具类
排序操作
- void reverse(List list):反转指定list集合元素的顺序
- void shuffle(List list):对List集合元素进行随机排序
- void sort(List list):对指定List集合的元素按升序进行排序
- void swap(List list,int i,int j):将指定集合中i处的元素和j处的元素进行互换
- void rotate(List list,int distance):当 distance为正数时,将List集合的后distance个元素“整体”移动到前面;为负就移到后面
查找排序操作
- Object max(Collection coll):根据元素的自然顺序返回给定集合中的最小值
- 。。。。
同步控制
- synchroniaedXXX():java集合中常见的HashSet、HashMap、ArrayList、LinkedList、HashMap都是线程不安全的,当有超过一个线程需要修改该集合就需要加上该方法来保证线程安全
- synchroniaedSet()、synchroniaedMap()、synchroniaedList()、synchroniaedCollection()