一、数组、对象数组、集合框架的特点与区别
1.概念
数组:用于存放同一基本数据类型元素的组合。 值类型也叫基本数据类型
对象数组:用于存放同一对象类型元素的组合。
集合框架:动态的对象数组。
2.区别
数组不能动态扩张,定义时必须指定长度;集合则无需指定长度,可动态扩张。
二、为什么需要集合框架?
如果不知道程序运行时需要多少对象,或者需要更复杂的方式类存储对象,可以使用集合框架,collection集合框架用来存储和操作不同类型的对象数组。
三、集合框架的体系
1:collection接口
Collection 接口主要有三个子接口:
Set——表示不允许有重复元素的集合
List——表示允许有重复元素的集合
Queue——队列,JDK1.5新增,与上面两个集合类主要是的区分在于Queue主要用于存储数据,而不是处理数据。队列是一种特殊的线性表,先进后出。
按照一定的规则进行排序,
Stack——继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。
堆栈:表示一个先进后出的数据结构,子弹夹
1.1List接口
1.1.1特点:(有序,可重复)
(1)和数组类似,可以动态增长;
(2)有序,对象可以重复;
(3)查找元素效率高,插入删除元素效率低(会引起其他元素位置改变)。
1.1.2遍历方式:
(1)下标
(2)foreach(>=JDK 1.5)
(3)迭代器Iterator
1.1.3:描述
默认长度为0,初始容量10,50%延长,相对节约空间
1.1.4:对应的实现类
1.1.4.1:Arraylist集合
1.1.4.1.1:描述
数组结构:默认长度为10,50%延长,相对节约空间。增长方式:*3/2+1
1.1.4.1.2:声明
ArrayList<E> al=new ArrayList<E>();
<E> 泛型,泛型可以为任何类型的对象,但不包括基本类型。
作用:它的好处在于存储时可以自动检查存入类型的合法性,取出时(get)可以自动转型成对应的类型
1.1.4.1.3:方法
1.1.4.1.3.1: 追加
boolean add(E e); //将指定的元素添加到此列表的尾部
void add(int index, E element); //将指定的元素插入此列表中的指定位置
boolean addAll(Collection); //将集合中的数据追加到另一个集合后面
boolean addAll(int index, Collection); //将Collection指定追加到位置之后
删除
void clear(); //移除集合中所有的元素
E remove(int index); //移除此列表中指定位置上的元素。
boolean remove(Object o); //移除此列表中首次出现的指定元素(如果存在)。
void removeRange(int fromIndex, int toIndex); //移除列表中索引在 fromIndex(包括)和 toIndex(不包括) 之间的所有元素。
修改(替换)
Object set(index, element); //将index位置的对象替换成element
1.1.4.1.3.4:获取
E get(int index); //返回集合中指定位置的对象
List subList(fromIndex, toIndex); //截取子集合
1.1.4.1.3.5:判断
boolean contains(Object o); //集合中是否包含该元素,需重写equals(比较整体)
boolean containsAll(Collection c); //比较的是集合中的值,是否包含子集合中的内容(比较内容)
boolean isEmpty(); //如果此列表中没有元素,则返回 true
int indexOf(Object o); //判断元素的索引位置,如果不包含元素,则返回-1
1.1.4.1.3.6:长度及调整大小
int size(); //返回集合的长度
void trimToSize(); //调整当前的容量为实际size的大小(提高性能)
1.1.4.1.4:优化
创建集合时给集合一个合适的初始值
1.1.4.2: LinkedList集合
1.1.4.2.1:特点
双向链表结构:LinkedList没有默认分配长度
1.1.4.2.2:方法
1.1.4.2.2.1:添加
void addFirst(E e); //将指定元素插入此列表的开头。
void addLast(E e); //将指定元素添加到列表的结尾。
1.1.4.2.2.2:读取
E getFrist(); //返回此列表的第一个元素。
E getLast(); //返回此列表的最后一个元素。
1.1.4.2.2.3:移除
E removeFrist(); //移除并返回此列表的第一个元素。
E removeLast(); //移除并返回此列表的最后一个元素。
1.1.4.3Vector集合
1.1.4.3.1:特点
安全的(按顺序排放的)底层是数组数据结构。线程同步,与ArrayList相同。
//长度为10,当超过10时,100%延长,变为20个(有点浪费空间)。增长方式:n*2
1.1.4.4:三者的区别
ArrayList: 是可变数组结构,那么插入速度慢,查询快;
Linkedlist:则是插入块,查询慢;
Vector: 什么都慢,但是严格保障安全性;
1.2Set接口
1.2.1:特点(无序、不可重复)
(1)无序,对象不可以重复(eqauls——eqauls从Object继承,默认比较的地址);
(2)查找元素效率低,插入删除元素效率高(不会引起元素位置改变)。
1.2.2:遍历方式
(1)foreach
(2)迭代器
1.2.3:对应的实现类
1.2.3.1:HashSet集合
1.2.3.1.1:方法
(1) 增
boolean add(E e); //如果集合中未包含指定元素,则添加指定元素
(2) 删
void clear(); //从集合中移除所有元素
boolean remove(Object o); //如果指定元素存在于集合中,则将其移除
************************************************
注意:Set集合中的HashSet因为是无序的,所以不像ArrayList那样用remove(index)指定下标的位置删除。
************************************************
(3) 查
Set集合中没有get();方法,因为它无序无编号的(不知道拿出来的是什么)。
解决办法 =============> 迭代器Iterator
迭代器Iterator作用:遍历Set集合或取Set集合中的值。
Iterator方法:
boolean hasNext(); //如果仍有元素可以迭代,则返回 true。
E next(); //返回迭代的下一个元素。
操作步骤:
第一: 声明迭代器(放到一个传送带上)
Iterator<String> 迭代名 = 集合名.iterator<String>();
例:Set ar = new HashSet();
ar.add("java01");
ar.add("java02");
ar.add("java03");
Iterator<String> it = ar.iterator<String>();
第二: 循环取出
while(it.hasNext()){
String str = it.next();
System.out.println(str);
}
1.2.3.1.2:注意
(1) 它不允许出现重复元素;
(2)不保证和政集合中元素的顺序
(3)允许包含值为null的元素,但最多只能有一个null元素。
1.2.3.2:TreeSet集合
是Set的一种变体——可以实现排序等功能的集合,它在讲对象元素添加到集合中时会自动按照某种比较规则将其插入到有序的对象序列中,并保证该集合元素组成的读uixiangxulie时刻按照“升序”排列。
1.2.4:面试题
如何证明Set集合中重复的数据是没有存进去还是替换了原来的?(面试)
解题思路:
只要证明存没存进去,就可以证明该题。
(没存进去,那就不存在替换;存进去了,那就是替换了原来的。)
那如何证明有没有存进去?
首先要先搞清java怎么判断2个对象是否相等
1. 先比较2个对象的身份证hashcode;
2. 再比较2个对象的equals是否相等。(是里和外比,还是外和里比?)
hashcode只是决定是否需要用equals来比较,真正决定对象是否相等的方法仍然是equals。
1.3 Queue接口
请看下面的博客-------------
2:Map接口
2.1:特点
(1)无序、以键值对的形式添加元素,键不能重复,值可以重复
2.2:遍历方式
(1)先取出保存所有键的Set,再遍历Set即可(2种)。
(2)先取出保存所有Entry的Set,再遍历此Set即可。
2.3: 描述
Map并不是一个真正意义上的集合,但是这个接口提供了三种“集合视角”,使得可以像操作集合一样操作。
2.4:对应的实现类
2.4.1:HashMap
2.4.1.1:特点
根据键的HashCode值存储数据,查询快,最多允许一个键为NULL,多个值为NULL。
线程不同步
2.4.1.2:方法
2.4.1.2.1:存储(以“键-值”的方式进行存储)
V put(K key, V value) //将指定的值与此映射中的指定键关联
例:mp.put("CN","中华人民共和国");
mp.put("RU","俄罗斯联邦");
mp.put("US","美利坚合众国");
2.4.1.2.2:读取
V get(Object key) //返回指定键所映射的值,如没有值则返回null
例:mp.get("CN"); //键值,而不是下标
2.4.1.2.3:删除
V remove(Object key) //如果存在一个键的映射关系,则移除
例:mp.remove("RU");
2.4.1.2.4:集合大小
int size() //返回此映射中的键-值映射关系数
2.4.1.2.5:包含
boolean containsKey(Object key);
boolean containsValue(Object value);
例:mp.containsKey("CN"); //是否包含CN键
2.4.1.2.6:其他方法
mp.keySet(); //输出所有键的集合(注意不包括值)
mp.values(); //输出键所对应的值,比如“中华人民共和国”
mp.entrySet(); //返回此映射所包含的映射关系的 Set 视图
2.4.2:Hashtable
与HashMap类似,但它不允许键或值为NULL。支持线程的同步(即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢)。
2.4.3:TreeMap
根据键排序(默认升序),也可指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。
2.4.4:LinkedHashMap
保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历 的时候会比HashMap慢。
2.4.5:如何快速遍历Map集合
遍历保存的Entry的set
Map<String, String> map=new HashMap<>();
map.put("zs", "张三");
map.put("ls", "李四");
map.put("ww", "五五");
map.put("zs", "张山");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey()+"\t"+entry.getValue());
}
四、其他
1 Iterator(迭代器):遍历集合List/Set
hasNext
next
remove:在遍历集合,并同时需要删除集合中的元素时,建议使用Iterator.remove
2 java.lang.Comparable:自然排序接口
2.1. 排序:
2.1.1:对List集合中的元素进行排序(默认升序)
Collections.sort(List list);
2.1.2:Collections类不知道按对象的哪个属性来排序,
因此我们要写个对象排序的规则类,让这个类实现Comparator接口,并重写compare方法(对排序规则进行重写),然后在排序的时候应用这个规则类。
例:
public class DogSort implements Comparator{ //实现Comparator接口
//重写compare方法,按年龄来排序
public int compare(Object o1, Object o2){ //比较两个对象
//强转Object对象
Dog d1=(Dog)o1;
Dog d2=(Dog)o2;
//如果d1对象的年龄 > d2对象的年龄
if(d1.getAge()>d2.getAge()){
return 1;
}
return -1;
}
}
调用时:Collections.sort(list, new DogSort()); //表示list集合按DogSort()的规则来排序。
2.2 反转:
对List集合中的元素进行反转操作
Collections.reverse(List list);
List<String> li=new ArrayList<>();
li.add("abc");
li.add("cab");
li.add("abb");
li.add("bac");
// List<Student> la=new ArrayList<>();
// la.add(new Student(1, "柳永", "男", 18, "湖南省长沙市", "18528589652", "2000-1-4"));
// la.add(new Student(2, "赵六", "男", 20, "湖南省衡阳市", "18608569752", "1998-8-21"));
// la.add(new Student(3, "刘芳", "女", 21, "湖南省常德市", "17688559452", "1997-5-15"));
//问题1:不利用reverse,硬编码实现集合元素的反向输出
// for (int i = li.size()-1; i >=0; i--) {
// System.out.println(li.get(i));
// }
//问题2:实现集合元素的反向转换
// List<String> la=new ArrayList<>();
// for (int i = li.size()-1; i >=0; i--) {
// la.add(li.get(i));
// }
// for (String s : la) {
// System.out.println(s);
// }
//问题3:将一个字符串进行反转,禁止使用reverse()方法
// String str="defgh";
// String[] s=str.split("");
// str="";
// for (int i = s.length-1; i >=0; i--) {
// str=str+s[i];
// }
// System.out.println(str);
2.3. 交换:
在指定列表的指定位置处交换元素
swap(List list, int i, int j);
例:Collections.swap(list, 0, list.size()-1); //把第1个与最后一个交换
for (int i = 0; i < la.size()/2; i++) {
// Student c = la.get(i);
// la.add(i, la.get(la.size()-1-i));
// la.remove(i+1);
// la.add(la.size()-1-i, c);
// la.remove(la.size()-1+-i);
// }
// for (Student s : la) {
// System.out.println(s);
// }
2.4. 取集合中最大或最小
max(List list);
min(List list);
String str=Collections.max(li);
// System.out.println(str);
// String str=Collections.min(li);
// System.out.println(str);
2.5. 复制:
将src集合中的所有元素复制到desc集合中
void copy(List dest, List src);
List<String> lb=new ArrayList<>();
// lb.add("");
// lb.add("");
// lb.add("");
// lb.add("");
// Collections.copy(lb, li);
// for (String s : lb) {
// System.out.println(s);
// }
3 java.util.Comparator:比较器接口
@Override
public int compareTo(Student o) {
// TODO Auto-generated method stub
return this.getSname().compareTo(o.getSname());
}
4. Collections:工具类
提供一组静态方法操作Collection集合
混乱的顺序:Collections.shuffle(list);
List<String> li=new ArrayList<>();
li.add("abc");
li.add("cab");
li.add("abb");
li.add("bac");
Collections.shuffle(li);
for (String s : li) {
System.out.println(s);
}
5.Arrays:工具类
提供了一组静态方法操作数组
Arrays.toString(字符串)
String[] str=new String[3];
str[0]="张三"; str[1]="李四";
str[2]="王五";
System.out.println(str);
System.out.println(Arrays.toString(str));
五、泛型
以类型作为参数的类就叫泛型。
作用:提高程序健壮性,简化代码
泛型的默认值是Object
六、装箱、拆箱
值类型->引用类型 装箱
引用类型->值类型 拆箱
JDK1.5之后引入了自动装箱及自动拆箱功能