1、Collection集合
1.1、集合的由来:
1)、我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储。
2)、而要想存储多个对象,就不能是一个基本的变量,而应该是一个容器类型的变量,在我们目前所学过的知识里面,有哪些是容器类型的呢?
3)、数组和StringBuffer。但是呢?StringBuffer的结果是一个字符串,不一定满足我们的要求,所以我们只能选择数组,这就是对象数组。
4)、而对象数组又不能适应变化的需求,因为数组的长度是固定的,这个时候,为了适应变化的需求,Java就提供了集合类供我们使用。
1.2、数组和集合的区别
A:长度区别
数组的长度固定
集合长度可变
B:内容不同
数组存储的是同一种类型的元素
而集合可以存储不同类型的元素
C:元素的数据类型问题
数组可以存储基本数据类型,也可以存储引用数据类型
集合只能存储引用类型
1.3、集合的继承体系
Collection
|--List
|--ArrayList
|--Vector
|--LinkedList
|--Set
|--HashSet
|--TreeSet
Collection:是集合的顶层接口,它的子体系有重复的,有唯一的,有有序的,有无序的。
1.4、Collection的功能概述
1:添加功能
boolean add(Object obj):添加一个元素
boolean addAll(Collection c):添加一个集合的元素,把一个集合的元素全部添加到另一个集合
2:删除功能
void clear():移除所有元素
boolean remove(Object o):移除一个元素
boolean removeAll(Collection c):移除一个集合的元素(只要有一个元素被移除了,就返回true。)
3:判断功能
boolean contains(Object o):判断集合中是否包含指定的元素
boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(只有包含所有的元素,才叫包含)
boolean isEmpty():判断集合是否为空
4:获取功能
Iterator iterator():迭代器,集合的专用遍历方式
Object next():获取元素,并移动到下一个位置。
NoSuchElementException:没有这样的元素,因为你已经找到最后了。
boolean hasNext():如果仍有元素可以迭代,则返回 true。
5:长度功能
int size():元素的个数
数组有没有length()方法呢?yes
字符串有没有length()方法呢?yes
集合有没有length()方法呢?no
6:交集功能
boolean retainAll(Collection c):两个集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢?
A对B做交集,最终的结果保存在A中,B不变。
返回值表示的是A是否发生过改变。没有返回true,发生了改变返回false
7:把集合转换为数组
Object[] toArray()
public class CollectionDemo {
public static void main(String[] args) {
Collection<String> c=new ArrayList<String>();
Collection<String> c1=new ArrayList<String>();
// * boolean add(Object obj):添加一个元素
// * boolean addAll(Collection c):添加一个集合的元素
c.add("hello");
c.add("world");
c.add("java");
c1.add("hello1");
c1.add("world1");
c1.add("java1");
System.out.println(c.size());
System.out.println("c:" + c);
c.addAll(c1);
System.out.println(c.size());
System.out.println("c:" + c);//c:[hello, world, java, hello1, world1, java1]
System.out.println(c1.size());
System.out.println("c:" + c1);//c:[hello1, world1, java1]
// * void clear():移除所有元素
// * boolean remove(Object o):移除一个元素
// * boolean removeAll(Collection c):移除一个集合的元素(只要有一个元素被移除了,就返回true。)
c.removeAll(c1);
System.out.println(c.size());
System.out.println("c:" + c);//c:[hello, world, java]
System.out.println(c1.size());
System.out.println("c:" + c1);//c:[hello1, world1, java1]
// * boolean contains(Object o):判断集合中是否包含指定的元素
// * boolean containsAll(Collection c):判断集合中是否包含指定的集合元素(只有包含所有的元素,才叫包含)
// * boolean isEmpty():判断集合是否为空
c.addAll(c1);
c.containsAll(c1);
System.out.println("containsAll:"+c.containsAll(c1));
System.out.println(c.size());
System.out.println("c:" + c);//c:[hello, world, java, hello1, world1, java1]
System.out.println(c1.size());
System.out.println("c:" + c1);//c:[hello1, world1, java1]
// boolean retainAll(Collection c):两个集合都有的元素?思考元素去哪了,返回的boolean又是什么意思呢?
//A对B做交集,最终的结果保存在A中,B不变。
//返回值表示的是A是否发生过改变。没有返回true,发生了改变返回false
c.retainAll(c1);
System.out.println("retainAll:"+c.retainAll(c));
System.out.println(c.size());
System.out.println("c:" + c);//c:[hello1, world1, java1]
System.out.println(c1.size());
System.out.println("c:" + c1);//c:[hello1, world1, java1]
// Object[] toArray():把集合转成数组,可以实现集合的遍历
Object[] obj=c.toArray();
Object[] obj1=c1.toArray();
for(Object x:obj){
System.out.print(x+",");
}
System.out.println();
for(Object x:obj1){
String ss=(String)x;//因为是object类型,所以要转成对应的String
System.out.print(ss+",");
}
System.out.println();
// 迭代器:Iterator<E> iterator()(重点)
Iterator<String> it=c.iterator();
while(it.hasNext()){
String ss=(String)it.next();//因为是object类型,所以要转成对应的String
System.out.print(ss+",");
}
System.out.println();
}
}
2、List集合
List集合的特点:
有序(存储和取出的元素一致),可重复的。
常见数据结构
A:栈 先进后出
B:队列 先进先出
C:数组 查询快,增删慢
D:链表 查询慢,增删快
List:(List的子类特点)
ArrayList:
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。
Vector:
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
LinkedList:
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。
List有三个儿子,我们到底使用谁呢?
看需求(情况)。
要安全吗?
要:Vector(即使要安全,也不用这个了,后面有替代的)
不要:ArrayList或者LinkedList
查询多:ArrayList
增删多:LinkedList
如果你什么都不懂,就用ArrayList。
List集合的特有功能:
A:添加功能
void add(int index,Object element):在指定位置添加元素
B:获取功能
Object get(int index):获取指定位置的元素
C:列表迭代器
ListIterator listIterator():List集合特有的迭代器
D:删除功能
Object remove(int index):根据索引删除元素,返回被删除的元素
E:修改功能
Object set(int index,Object element):根据索引修改元素,返回被修饰的元素
List特有点遍历方式:size()和get()的结合
size():获取集合的长度
get():获取元素
public class ListDemo {
public static void main(String[] args) {
List<String> l=new ArrayList<String>();
l.add("hello");
l.add("world");
l.add("java");
Iterator<String> i=l.iterator();
while(i.hasNext()){
String ss=(String)i.next();
System.out.print(ss+",");
}
System.out.println();
//List特有点遍历方式:size()和get()的结合
for(int x=0;x<l.size();x++){
String ss=(String)l.get(x);
System.out.print(ss+",");
}
System.out.println();
}
}
3、List的子类
3.1、List的子类特点
ArrayList:
底层数据结构是数组,查询快,增删慢
线程不安全,效率高
Vector:
底层数据结构是数组,查询快,增删慢
线程安全,效率低
LinkedList:
底层数据结构是链表,查询慢,增删快
线程不安全,效率高
3.2、LinkedList功能
* LinkedList的特有功能:
* A:添加功能
* public void addFirst(Object e)
* public void addLast(Object e)
* B:获取功能
* public Object getFirst()
* public Obejct getLast()
* C:删除功能
* public Object removeFirst()
* public Object removeLast()
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList<String> link = new LinkedList<String>();
// 添加元素
link.add("hello");
link.add("world");
link.add("java");
link.addFirst("javaee");
System.out.println("link:" + link);
link.addLast("android");
System.out.println("link:" + link);
System.out.println("getFirst:" + link.getFirst());
System.out.println("getLast:" + link.getLast());
System.out.println("removeFirst:" + link.removeFirst());
System.out.println("removeLast:" + link.removeLast());
// 输出对象名
System.out.println("link:" + link);
}
}
4、泛型
泛型:是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。参数化类型,把类型当作参数一样的传递。
一般来说就是在集合中使用。
格式:
<数据类型>
此处的数据类型只能是引用类型。
泛型高级(通配符)
?:任意类型,如果没有明确,那么就是Object以及任意的Java类了
? extends E:向下限定,E及其子类
? super E:向上限定,E极其父类
// ?表示任意的类型都是可以的
Collection<?> c5 = new ArrayList<Object>();
Collection<?> c6 = new ArrayList<Animal>();
Collection<?> c7 = new ArrayList<Dog>();
Collection<?> c8 = new ArrayList<Cat>();
// ? extends E:向下限定,E及其子类
// Collection<? extends Animal> c9 = new ArrayList<Object>();
Collection<? extends Animal> c10 = new ArrayList<Animal>();
Collection<? extends Animal> c11 = new ArrayList<Dog>();
Collection<? extends Animal> c12 = new ArrayList<Cat>();
// ? super E:向上限定,E极其父类
Collection<? super Animal> c13 = new ArrayList<Object>();
Collection<? super Animal> c14 = new ArrayList<Animal>();
5、Set集合
* Collection
* |--List
* 有序(存储顺序和取出顺序一致),可重复
* |--Set
* |--HashSet
* |--TreeSet
* 无序(存储顺序和取出顺序不一致),唯一
*
* HashSet:它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。
* 注意:虽然Set集合的元素无序,但是,作为集合来说,它肯定有它自己的存储顺序,
*
* HashSet:存储字符串并遍历
* 问题:为什么存储字符串的时候,字符串内容相同的只存储了一个呢?
* 通过查看add方法的源码,我们知道这个方法底层依赖 两个方法:hashCode()和equals()。
* 步骤:
* 首先比较哈希值
* 如果相同,继续走,比较地址值或者走equals()
* 如果不同,就直接添加到集合中
*
* LinkedHashSet:底层数据结构由哈希表和链表组成。
* 哈希表保证元素的唯一性。
* 链表保证元素有素。(存储和取出是一致)
*
* TreeSet:能够对元素按照某种规则进行排序。
* TreeSet集合的特点:排序(从小到大)和唯一(不可重复)
* 排序有两种方式
* A:自然排序
* B:比较器排序
public class SetDemo {
public static void main(String[] args) {
Set<String> set=new HashSet<String>();
set.add("hello");
set.add("java");
set.add("world");
set.add("java"); //不可重复
set.add("world");//不可重复
for(String s:set){
System.out.print(s+",");
}
System.out.println();
// LinkedHashSet:底层数据结构由哈希表和链表组成。
LinkedHashSet<String> lhs=new LinkedHashSet<String>();
lhs.add("hello");
lhs.add("java");
lhs.add("world");
for(String s:lhs){
System.out.print(s+",");
}
System.out.println();
//TreeSet
TreeSet<Integer> ts=new TreeSet<Integer>();
ts.add(20);
ts.add(18);
ts.add(23);
ts.add(22);
ts.add(17);
ts.add(24);
ts.add(19);
ts.add(18);
ts.add(24);
for(Integer i:ts){
System.out.print(i+",");
}
System.out.println();
}
}
6、Map集合
6.1、Map集合的特点
* Map集合的特点:
* 将键映射到值的对象。Map集合存储元素是成对出现的,Map集合的键是唯一的,值是可重复的。
*
* Map集合的数据结构值针对键有效,跟值无关
* HashMap:用来保证键的唯一性的
* TreeMap:是基于红黑树的Map接口的实现。
* Collection集合的数据结构是针对元素有效
*
* LinkedHashMap:是Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。
* 由哈希表保证键的唯一性
* 由链表保证键盘的有序(存储和取出的顺序一致)
6.2、Map集合的功能概述
* 1:添加功能
* V put(K key,V value):添加元素。这个其实还有另一个功能?先不告诉你,等会讲
* 如果键是第一次存储,就直接存储元素,返回null
* 如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
* 2:删除功能
* void clear():移除所有的键值对元素
* V remove(Object key):根据键删除键值对元素,并把值返回
* 3:判断功能
* boolean containsKey(Object key):判断集合是否包含指定的键
* boolean containsValue(Object value):判断集合是否包含指定的值
* boolean isEmpty():判断集合是否为空
* 4:获取功能
* Set<Map.Entry<K,V>> entrySet():返回的是键值对对象的集合
* V get(Object key):根据键获取值
* Set<K> keySet():获取集合中所有键的集合
* Collection<V> values():获取集合中所有值的集合
* 5:长度功能
* int size():返回集合中的键值对的对数
*
* 1:Hashtable和HashMap的区别?
* Hashtable:线程安全,效率低。不允许null键和null值
* HashMap:线程不安全,效率高。允许null键和null值
*
* 2:List,Set,Map等接口是否都继承子Map接口?
* List,Set不是继承自Map接口,它们继承自Collection接口
* Map接口本身就是一个顶层接口
public class MapDemo {
public static void main(String[] args) {
Map<String, String> map=new HashMap<String,String>();
// 添加元素,键唯一,值可以重复
// V put(K key,V value):添加元素
map.put("文章", "马伊俐");
map.put("文章", "姚笛");
System.out.println("put:"+map );//put:{文章=姚笛}
map.put("马伊俐", "文章");
map.put("姚笛", "文章");
System.out.println("put:"+map );//put:{文章=姚笛, 姚笛=文章, 马伊俐=文章}
map.put("邓超", "孙俪");
map.put("黄晓明", "杨颖");
map.put("周杰伦", "蔡依林");
map.put("刘恺威", "杨幂");
System.out.println("put:"+map );
// * 2:删除功能
// * void clear():移除所有的键值对元素
// * V remove(Object key):根据键删除键值对元素,并把值返回
System.out.println("v:"+map.remove("文章"));
System.out.println("put:"+map );
// * 3:判断功能
// * boolean containsKey(Object key):判断集合是否包含指定的键
// * boolean containsValue(Object value):判断集合是否包含指定的值
// * boolean isEmpty():判断集合是否为空
System.out.println(map.containsKey("文章"));
System.out.println(map.containsValue("文章"));
System.out.println(map.isEmpty());
// * 4:获取功能
// * Set<Map.Entry<K,V>> entrySet():返回的是键值对对象的集合
// * V get(Object key):根据键获取值
// * Set<K> keySet():获取集合中所有键的集合
// * Collection<V> values():获取集合中所有值的集合
System.out.println(map.get("邓超"));
Set<String> set1=map.keySet();
System.out.print("getkey:");
for(String s:set1){
System.out.print(s+",");
}
System.out.println();
Collection<String> con1=map.values();
System.out.print("getValue:");
for(String s:con1){
System.out.print(s+",");
}
System.out.println();
//Set<Map.Entry<K,V>> entrySet():返回的是键值对对象的集合
Set<Map.Entry<String, String>> set2=map.entrySet();
for(Map.Entry<String, String> me:set2){
String key=me.getKey();
String value=me.getValue();
System.out.print(key+"--"+value+",");
}
System.out.println();
}
}