Java集合框架
集合框架被设计成要满足以下几个目标。
-
该框架必须是高性能的。基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。
-
该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性。
-
对一个集合的扩展和适应必须是简单的。
从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,List、Set 和 Queue(这个现在基本被淘汰),再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap
等等。
集合框架是一个用来代表和操纵集合的统一架构。所有的集合框架都包含如下内容:
-
接口:是代表集合的抽象数据类型。例如 Collection、List、Set、Map 等。之所以定义多个接口,是为了以不同的方式操作集合对象
-
实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap。
-
算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。
除了集合,该框架也定义了几个 Map 接口和类。Map 里存储的是键/值对。尽管 Map 不是集合,但是它们完全整合在集合中。
Collection接口
Collection 层次结构中的根接口,所有的子接口和实现类都会具有他的功能
- Collection接口的方法 : 添加
add (存储元素)
元素存储到集合中addAll (Collection c)
将一个集合的元素,添加到另一个集合
- Collection接口的方法 : 移除
boolean remove(元素)
移除集合中指定的元素removeAll(Collection c)
) 移除两个集合中相同元素
- Collection接口的方法 : 包含
boolean contains(元素)
判断元素是否包含在集合中boolean containsAll(Collection c)
判断一个集合中的元素是否完全包含在另一个集合中
- Collection接口的方法 : 其他
int size()
返回集合的长度,就是集合中元素的个数- Java中的长度三种表示 : 数组.length 属性 , 字符串.length() 方法, 集合.size()方法
void clear()
清空集合中的所有元素, 集合容器本身依然可以使用boolean isEmpty()
判断集合中是否有元素,集合的长度是0,方法返回trueObject[] toArray()
集合中的元素转成数组retainAll(Collection c)
两个集合取交集
Collections工具类
java.util.Collections
集合操作的工具类,提供方法来操作集合,方法全部是静态方法
方法 :
static void shuffle(List list)
集合元素随机排列static void sort(List list)
集合中元素的自然顺序排序static void sort(List list,Comparator c)
比较器的顺序进行排序static 传递什么返回什么 synchronized开头(传递集合)
线程不安全集合,变成安全的集合- Comparator 是比较器接口, 自定义实现类,重写方法
public static void main(String[] args) {
List<Person> list = new ArrayList<Person>();
list.add(new Person("a",10));
list.add(new Person("b",9));
list.add(new Person("b",12));
list.add(new Person("b",11));
list.add(new Person("b",10));
System.out.println(list);
//static void sort(List list,Comparator c) 比较器的顺序进行排序
Collections.sort(list, new Comparator<Person>() {
public int compare(Person p1,Person p2) {
return p1.getAge() - p2.getAge();
}
});
System.out.println(list);
}
}
//接口的实现类,重写方法,泛型<T> 写要比较对象
class MyComparator implements Comparator<Person>{
//方法的参数是两个对象, 参数比较的对象
public int compare(Person p1,Person p2) {
//System.out.println(p1.getAge() - p2.getAge());
return p1.getAge() - p2.getAge();
}
}
迭代器 Iterator
迭代器是集合的遍历方式, 迭代器是所有的Collection集合的通用遍历方式.
接口 : java.util.Iterator
迭代器对象
- Iterator接口的方法
boolean hasNext()
判断集合中是否有下一个元素,如果有返回trueE next()
取出集合中的下一个元素void remove()
移除元素,遍历到哪个元素,删除哪个元素
- Iterator接口的实现类
- 接口实现类的对象,是获取来的,不是我们new的
- Collection接口中定义方法 : iterator() 作用获取迭代器接口 Iterator的实现类对象
- Collection col = new ArrayList(); Collection接口中有方法 iterator(),ArrayList重写
- 对象 col.iterator() 拿到迭代器接口的实现类对象
public static void main(String[] args) {
//创建集合
Collection<String> coll = new ArrayList<String>();
//存储元素
coll.add("hello");
coll.add("World");
coll.add("my");
coll.add("java");
//1. 获取迭代器接口Iterator的实现类对象
//集合对象的方法 iterator()
Iterator<String> it = coll.iterator();
//2. 迭代器对象的方法 hasNext() 判断是否有元素
//boolean b = it.hasNext();
//System.out.println(b);
//3. 迭代器对象的方法 next() 取出元素
//String str = it.next();
//System.out.println(str);
//循环中,反复调用方法 hasNext()
while ( it.hasNext() ) {
//取出元素
String str = it.next();
System.out.println(str);
}
}
增强for循环
增强型的for循环,出现在JDK1.5版本.
java.lang.Iterable
接口 实现这个接口允许对象成为 “foreach” 语句的目标。 含数组
谁是接口的实现类 : Collection继承接口Iterable
格式 :
for(数据类型 变量名 : 集合或者数组){
}
好处 : 减少代码量
弊端 : 无索引,不能修改容器中的元素内容
遍历数组
public static void array() {
int[] arr = {1,3,5,7,9};
for(int i : arr) {
System.out.println(i+1);
}
System.out.println(arr[0]);
}
遍历集合
public static void list() {
List<String> list = new ArrayList<String>();
list.add("how");
list.add("do");
list.add("you");
list.add("do");
for(String s : list) {
System.out.println(s);
}
System.out.println("==========");
List<Person> listPerson = new ArrayList<Person>();
listPerson.add(new Person("a1",101));
listPerson.add(new Person("a2",102));
listPerson.add(new Person("a3",103));
listPerson.add(new Person("a4",104));
for(Person p : listPerson) {
System.out.println(p);
}
}
增强for循环是个假象
属于编译特效 : javac搞事情
for遍历数组 : javac 编译为传统for形式
for遍历集合 : javac 编译为迭代器
Set集合
java.util.Set
接口, 继承父接口Collection
Set集合特点:
- 不包含重复元素
- 没有索引
- 无序
Set接口方法
Set接口的方法和父接口Collection方法,完全一样
public static void main(String[] args) {
//Set接口和实现类HashSet创建对象
Set<String> set = new HashSet<String>();
set.add("abc");
set.add("how");
set.add("are");
set.add("you");
//迭代器遍历
Iterator<String> it = set.iterator();
while(it.hasNext()) {
String str = it.next();
System.out.println(str);
}
System.out.println("======");
//增强for循环遍历
for(String str : set) {
System.out.println(str);
}
}
Set接口实现类HashSet
java.util.HashSet
类,实现接口Set
HashSet集合特点:
- 底层数据结构是哈希表
- 是由HashMap支持的
- HashSet集合,所有功能,都是由HashMap提供
- 无序的集合, 元素存储的顺序和取出的顺序不一致
- 线程不安全集合,运行速度快
public static void main(String[] args) {
//Set接口和实现类HashSet创建对象
Set<String> set = new HashSet<String>();
set.add("d");
set.add("c");
set.add("a");
set.add("b");
System.out.println(set);
}
LinkedHashSet用法
LinkedHashSet继承自HashSet,源码更少、更简单,唯一的区别是LinkedHashSet内部使用的是LinkHashMap。这样做的意义或者好处就是LinkedHashSet中的元素顺序是可以保证的,也就是说遍历序和插入序是一致的。
package HomeWork;
import java.util.LinkedHashSet;
import java.util.Scanner;
public class Demo3 {
public static void main(String[] args) {
System.out.println("输入一个字符串:");
Scanner scanner = new Scanner(System.in);
String string = scanner.next();
LinkedHashSet<Character> linkedHashSet = new LinkedHashSet<>();
//把字符串变成单个字母的数组
char[] arr = string.toCharArray();
//集合里插入元素
for(char b:arr) {
linkedHashSet.add(b);
}
//遍历排序后的数组
for(Character b:linkedHashSet) {
System.out.print(b);
}
}
}
输入:aabbcc
输出结果为:abc
HashSet去除重复元素的原理
Set接口创建引用型对象是会创建他的实现类HashSet,在储存对象是,集合会调用方法hashCode()
计算出储存元素的哈希值,根据哈希值确定其存储位置,在储存位置上如果已经有元素,就会让后来的对象
调用方法equals()传递先来的对象,两个对象哈希值相同,equals方法返回true,判断为相同元素,就不在储存后来的元素
这就是HashSet去除重复元素的原理。
List接口
java.util. List
接口继承Collection接口
接口的特点
- 有序, 元素在集合中,存储和取出的顺序一致
- 允许存储重复元素的集合
- 该接口中都是带有索引的
接口方法
带有索引的方法学习
add(int index,存储元素)
将元素,存储到指定的索引上元素 get(int index)
返回指定索引上的元素元素 remove(int index)
移除指定索引上的元素,返回被删除之前的元素元素 set(int index ,修改的元素)
修改指定索引上的元素,返回被修改之前的List subList(int begin,int end)
截取集合的一部分,包含开始索引,不包含结尾索引
public static void main(String[] args) {
mySubList();
}
/*
* subList(int begin, int end)
*/
public static void mySubList() {
//接口多态,创建对象
List<String> list = new ArrayList<String>();
//集合存储元素
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
System.out.println(list);
//截取集合的元素
List<String> newList = list.subList(1, 4);
System.out.println(newList);
}
/*
* set(int index ,要修改的元素)
*/
public static void mySet() {
//接口多态,创建对象
List<String> list = new ArrayList<String>();
//集合存储元素
list.add("a");
list.add("b");
list.add("c");
System.out.println(list);
//修改2索引上的元素, 大写C
String str = list.set(2, "C");
System.out.println(list);
System.out.println(str);
}
/*
* remove(int index)
*/
public static void myRemove() {
//接口多态,创建对象
List<String> list = new ArrayList<String>();
//集合存储元素
list.add("a");
list.add("b");
list.add("c");
System.out.println(list);
//移除1索引上的元素
String str = list.remove(1);
System.out.println(list);
System.out.println(str);
}
/*
* get(int index)
*/
public static void myGet() {
//接口多态,创建对象
List<String> list = new ArrayList<String>();
//集合存储元素
list.add("a");
list.add("b");
list.add("c");
System.out.println(list);
//获取指定索引上的元素
String str = list.get(0);
System.out.println(str);
}
/*
* add(int index , 存储元素)
*/
public static void myAdd() {
//接口多态,创建对象
List<String> list = new ArrayList<String>();
//集合存储元素
list.add("a");
list.add("b");
list.add("c");
System.out.println(list);
//在指定的索引上添加元素
list.add(2, "d");
System.out.println(list);
}
ArrayList集合
java.util.ArrayList
集合,类实现了接口List (有序,索引,重复)
ArrayList集合,底层是采用数组结构实现,大小可变数组 (复制)
查询速度快,增删速度慢
ArrayList是一个线程不安全的集合,运行速度快
ArrayList集合用法
- 集合的构造方法 : new 无参数的构造方法
- 创建长度为10个的集合, ArrayList底层是数组,数组的长度是10
- 集合的构造方法 : new 有参数的构造方法,传递int类型参数
- 参数是指定数组的长度的
- 向集合存储元素,和取出元素
public static void main(String[] args) {
//定义集合,存储自定义的对象Person
ArrayList<Person> array = new ArrayList<Person>();
array.add( new Person("张三",20) );
array.add( new Person("李四",21) );
array.add( new Person("王五",22) );
//迭代器遍历
Iterator<Person> it = array.iterator();
while(it.hasNext()) {
Person p = it.next();
System.out.println(p);
}
System.out.println("===========");
/*
* List接口实现类,ArrayList集合具有索引
* 利用索引来遍历 集合方法size()
* get(索引) 返回对应的元素
*/
for(int i = 0 ; i < array.size() ; i++) {
Person p = array.get(i);
System.out.println(p);
}
}
ArrayList集合数组扩容 新容量 = 老容量 + 老容量/2
LinkedList集合
java.util.LinkedList
实现List接口 (有序,索引,重复)
底层数据结果是链表结构, 双向链表
查询速度慢,增删速度快
线程不安全的,运行速度快
特性的内容 : 专门有方法,操作链表的开头元素和结尾元素
LinkedList特有方法
- 向链表的开头和结尾插入元素
addFirst(元素)
链表开头插入元素addLast(元素)
链表结尾插入元素
- 获取链表的开头和结尾元素
元素 getFirst()
获取链表的开头元素元素 getLast()
获取链表的结尾元素
- 删除链表的开头和结尾元素
元素 removeFirst()
删除链表的开头元素,返回被删除的元素元素 removeLast()
删除链表的结尾元素,返回被删除的元素
- push和pop方法
push(元素)
元素压入栈中元素 pop()
栈中弹出元素
public static void main(String[] args) {
myPushPop();
}
/*
* push()
* pop()
*/
public static void myPushPop() {
LinkedList<String> link = new LinkedList<String>();
link.add("a");
link.add("b");
link.add("c");
link.add("d");
System.out.println(link);
//栈中推入元素
link.push("e"); //开头添加
System.out.println(link);
//栈中弹出元素
String pop = link.pop(); //移除开头
System.out.println(pop);
System.out.println(link);
}
/*
* removeFirst()
* removeLast()
*/
public static void myRemove() {
LinkedList<String> link = new LinkedList<String>();
link.add("a");
link.add("b");
link.add("c");
link.add("d");
System.out.println(link);
//移除链表开头和结尾
String first = link.removeFirst();
String last = link.removeLast();
System.out.println(first);
System.out.println(last);
System.out.println(link);
}
/*
* getFirst()
* getLast()
*/
public static void myGet() {
LinkedList<String> link = new LinkedList<String>();
link.add("a");
link.add("b");
link.add("c");
link.add("d");
System.out.println(link);
//获取开头和结尾元素
String first = link.getFirst();
String last = link.getLast();
System.out.println(first);
System.out.println(last);
System.out.println(link);
}
/*
* addFirst()
* addLast()
*/
public static void myAdd() {
LinkedList<String> link = new LinkedList<String>();
link.add("a");
link.add("b");
link.addLast("h");
link.add("c");
link.add("d");
System.out.println(link);
//开头插入元素
link.addFirst("e");
System.out.println(link);
//尾部插入元素
link.addLast("f");
System.out.println(link);
}
Map集合
Java.util.map
接口,也是集合容器
●Collection集合存储元素每次只能存储单个的元素
●Map集合存储元素每次需要存储两个元素
-
一个元素做为键,一个元素做为值
-
一个集合中,键必须保证唯-性
-
一个键只能映射一一个值
Map接口的方法
v put(k,v)
,将键值对存储到集合中v get(k) 返回对应的值,集合中没有这个键,返回null
boolean containsValue(V) 判断集合中是否包含此值,包含返回true
V remove(K)
移除集合中的键值对,返回被移除之前的值Conllection<V> values()
集合中的所有的值取出,存储到Collection集合
public static void main(String[] args) {
myput();
myget();
myContains();
myremove();
myvalues();
}
/*
* Map接口方法values()
*/
public static void myvalues() {
//创建Map集合,键是字符串,值是整数
Map<String , Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 3);
map.put("c", 4);
Collection<Integer> coll = map.values();
for(Integer integer : coll) {
System.out.println(integer);
}
}
/*
* Map接口方法remove
*/
public static void myremove() {
//创建Map集合,键是字符串,值是整数
Map<String , Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 3);
map.put("c", 4);
//集合方法remove,移除键值对
Integer value = map.remove("c");
System.out.println(map);
}
/*
* Map接口方法 containsKey,contiansValue
*/
public static void myContains() {
//创建Map集合,键是字符串,值是整数
Map<String , Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 3);
map.put("c", 4);
//判断是否包含键
boolean b = map.containsKey("a");
System.out.println(b);
//判断是否包含此值
boolean v = map.containsValue(1);
System.out.println(v);
}
/*
* Map接口方法get
*/
public static void myget() {
//创建Map集合,键是字符串,值是整数
Map<String , Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 3);
map.put("c", 4);
//集合方法get(),传递键,获取值
//如果对应的键没有值,就返回null
Integer value = map.get("d");
System.out.println(value);
}
/*
* Map接口方法put
*/
public static void myput() {
//创建Map集合,键是字符串,值是整数
Map<String , Integer> map = new HashMap<>();
//集合方法put存储键值对
map.put("a", 1);
map.put("b", 3);
map.put("c", 4);
//键有重复时,前一个值会被覆盖
map.put("d", 3);
map.put("d", 5);
System.out.println(map);
}
Map集合遍历一
Map的遍历方式:键找值方式
Map接口定义方法:Set<k>keySet( ) Map
集合的键,取出,存储在set集合
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("abc", 123);
map.put("bcd", 124);
map.put("cde", 345);
//map集合方法keyset()获取 存储键的set集合
Set<String> set = map.keySet();
//遍历Set集合
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()) {
//取出set集合元素,Map的键
String key = iterator.next();
//map集合键,找值
Integer value = map.get(key);
System.out.println(key+"=="+value);
}
}
Map集合遍历二
键值对的映射关系遍历,Map.Entry接口,实现类对象表示了键值对的对应关系,拿到Map.Entry接口实现类对象
- Entry接口的方法
K getKey()
取出集合中的键V getValue()
取出集合中的值
- Map接口定义方法
Set<Entry<K,V>> entrySet()
集合中的键值对映射关系对象,Entry接口对象存储在Set集合
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("abc", 123);
map.put("bcd", 124);
map.put("cde", 345);
//1.Map集合方法entrySet() 获取到Entry接口实现类对象,存储Set集合
Set<Map.Entry<String,Integer>> set = map.entrySet();
//2.遍历set集合
Iterator<Map.Entry<String,Integer>> iterator = set.iterator();
while(iterator.hasNext()) {
//3.取出Set集合中的元素,是Entry接 口的实现类对象(键值对的对应关系)
Map.Entry<String, Integer> entry = iterator.next();
//4.Entry接口对象,调用方法getKey(), getValue()
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key+"=="+value);
}
增强for循环间接遍历Map集合
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
Set<Map.Entry<String, Integer>> set = map.entrySet();
for (Entry<String, Integer> entry : set) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println(key + " = " + value);
}
}
HashMap
java.util.HashMap
类实现Map接口
- HashMap集合特点
- 底层是哈希表结构,数组+链表(jdk1.8后变成数组+链表+红黑树)
- 保证存储到键对象的唯一性,作为键的对象,必须重写hashcode和equals
- 链表长度达8个,转成红黑树(尾插)
- 集合运行存储null值,null键
LinkedHashMap
java. uti1. LinkedHashMap
类继承HashMap,实现Map接口
java. uti1. LinkedHashset
类继承HashSet实现Set接口
- LinkedHashMap集合特点
-
底层数据结构是哈希表,子类是双向链表
-
集合是有序的集合,存储和取出的顺序一致
-
线程不安全集合,运行速度快
-
public static void main(String[] args) {
LinkedHashMap<String,String> linked = new LinkedHashMap<String,String>();
linked.put("b", "2");
linked.put("a", "3");
linked.put("h", "4");
linked.put("g", "5");
System.out.println(linked);
}
```
Hashtable
java. uti1. Hashtable
类实现Map接口
- Hashtable集合特点
- 底层是哈希表结构
- 不能存null值nul键(抛出空指针异常)
- 线程安全的集合,运行速度慢
- 从JDK1.2版本开始,被更加先进的HashMap取代
- Vector集合, List接口实现类
- 线程安全的,可变数组实现
- 从JDK1.2开始,被更加先进的ArrayList取代
Properties
集合框架和数组,属于临时性数据,数据在内存中存储
程序退出了,关机了,数据就会消失
和IO流技术结合,实现数据的持久化
java.util.Properties
类,继承Hashtable,实现接口Map
键值对存储的集合,所有的Map的使用方式,在Properties中全部使用
没有泛型的集合,类定义中,没有使用泛型技术
Properties集合中键值对的数据类型,被锁定为String类型
Properties设计失误的类
不能使用多态,设计存在失误
Properties特有的方法
setProperty(String key,String value)
键值对存储到集合中,setProperty == putgetProperty(String key)
返回指定键值对的值stringPropertyNames()
集合的全部键,存储到Set集合
public static void main(String[] args) {
//创建集合对象
Properties properties = new Properties();
//存储键值对
properties.setProperty("a", "1");
properties.setProperty("b", "2");
properties.setProperty("c", "3");
System.out.println(properties);
//取出键值对
String value = properties.getProperty("a");
System.out.println(value);
//遍历集合
Set<String > set = properties.stringPropertyNames();
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()) {
String key = iterator.next();
String value1 = properties.getProperty(key);
System.out.println(key+"=="+value1);
}
}
集合面试题
HashMap 和 Hashtable 有什么区别?
- hashMap去掉了HashTable 的contains方法,但是加上了containsValue()和containsKey()方法。
- hashTable同步的,而HashMap是非同步的,效率上逼hashTable要高。
- hashMap允许空键值,而hashTable不允许。
如何决定使用 HashMap 还是 TreeMap?
对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行遍历,TreeMap是更好的选择。基于你的collection的大小,也许向HashMap中添加元素会更快,将map换为TreeMap进行有序key的遍历。
HashMap的底层原理
HashMap概述: HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
HashMap的数据结构: 在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。
当我们往Hashmap中put元素时,首先根据key的hashcode重新计算hash值,根绝hash值得到这个元素在数组中的位置(下标),如果该数组在该位置上已经存放了其他元素,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放入链尾.如果数组中该位置没有元素,就直接将该元素放到数组的该位置上。
需要注意Jdk 1.8中对HashMap的实现做了优化,当链表中的节点数据超过八个之后,该链表会转为红黑树来提高查询效率,从原来的O(n)到O(logn)
HashSet的底层原理
- HashSet底层由HashMap实现
- HashSet的值存放于HashMap的key上
- HashMap的value统一为PRESENT
ArrayList 和 LinkedList 的区别是什么?
最明显的区别是 ArrrayList底层的数据结构是数组,支持随机访问,而 LinkedList 的底层数据结构是双向循环链表,不支持随机访问。使用下标访问一个元素,ArrayList 的时间复杂度是 O(1),而 LinkedList 是 O(n)。
如何实现数组和 List 之间的转换?
List转换成为数组:调用ArrayList的toArray方法。
数组转换成为List:调用Arrays的asList方法。
ArrayList 和 Vector 的区别是什么?
Vector是同步的,而ArrayList不是。然而,如果你寻求在迭代的时候对列表进行改变,你应该使用CopyOnWriteArrayList。
ArrayList比Vector快,它因为有同步,不会过载。
ArrayList更加通用,因为我们可以使用Collections工具类轻易地获取同步列表和只读列表。
Array 和 ArrayList 有何区别?
Array可以容纳基本类型和对象,而ArrayList只能容纳对象。
Array是指定大小的,而ArrayList大小是固定的。
Array没有提供ArrayList那么多功能,比如addAll、removeAll和iterator等。
在 Queue 中 poll()和 remove()有什么区别?
poll() 和 remove() 都是从队列中取出一个元素,但是 poll() 在获取元素失败的时候会返回空,但是 remove() 失败的时候会抛出异常。
哪些集合类是线程安全的?
vector:就比arraylist多了个同步化机制(线程安全),因为效率较低,现在已经不太建议使用。在web应用中,特别是前台页面,往往效率(页面响应速度)是优先考虑的。
statck:堆栈类,先进后出。
hashtable:就比hashmap多了个线程安全。
enumeration:枚举,相当于迭代器。
迭代器 Iterator 是什么?
迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。
Iterator 怎么使用?有什么特点?
Java中的Iterator功能比较简单,并且只能单向移动:
-
使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。
-
使用next()获得序列中的下一个元素。
-
使用hasNext()检查序列中是否还有元素。
-
使用remove()将迭代器新返回的元素删除。
Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。
Iterator 和 ListIterator 有什么区别?
Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。
Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。
ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。