1.集合:动态存储多个引用数据类型变量的容器,它空间可扩展(动态数组,实际上是数组的复制迁移)。
2.集合中常用概念:
- 有序:按添加的顺序来存值就叫有序。
- 可排序:按照一定规则(比如按数字由小到大或大到小,按字典顺序)来排序并存值。
- 唯一性:不可重复。
3.集合家族系谱图:
3.1:Collection:存储无序,可重复的单一对象
3.1.1:List:存储有序,可重复的单一对象
1:ArrayList:存储有序,可重复的单一对象,底层采用Object[]存值;
2:LinkedList:存储有序,可重复的单一对象,底层采用双向链表结构存值;
3.1.2:Set:存储无序,唯一的单一对象
1:HashSet:存储无序,唯一的单一对象,底层采用HashMap的Key存值;
2:TreeSet:存储无序,但是可排序的,唯一的单一对象,底层采用TreeMap的Key存值
3.2:Map:按Key-Value对方式存值
3.2.1:HashMap:按key-value对的方式存值,Key是无序唯一的单一对象.底层采用数组+链表结构存值。
3.2.2:TreeMap:按key-value对的方式存值,key是无序的可排序的唯一的单一对象.底层采用红黑二叉树结构存值。
4.ArrayList:存储有序,可重复的单一对象.底层采用Object[]存值。一般情况下按原来1.5倍扩容。
优点:遍历访问集合中元素和修改集合中元素效率高
缺点:按照指定索引添加和删除元素效率低
后续补图
public static void main(String[] args) {
//创建集合对象
List alist=new ArrayList();
//向集合中添加对象
alist.add(11);//0
alist.add(22);//1
//向集合中指定索引处添加集合对象,索引取值范围[0,集合.size()]
alist.add(0, 66);//0
//遍历集合
for (Object ob : alist) {
System.out.println(ob);
}
System.out.println("--------------------");
//修改集合中指定索引处的元素对象,0<=索引的范围<集合.size()
alist.set(0, 77);
//遍历集合
for (int i = 0; i < alist.size(); i++) {
System.out.println(alist.get(i));
}
System.out.println("*******************************");
//按照索引删除集合中元素对象,0<=索引的范围<集合.size()
alist.remove(1);
//按照元素对象删除
alist.remove((Object)22);
//遍历集合
for (Object ob : alist) {
System.out.println(ob);
}
System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
//清空集合
alist.clear();
//遍历集合
for (Object ob : alist) {
System.out.println(ob);
}
}
5.过滤器(filter):将不需要的数据过滤出去,将需要的数据留下
/**
* 过滤器类
*/
public class MyFilter implements Predicate{
/**
* 重写过滤器中过滤方法
* @param t 代表集合中每个元素对象
* @return
*/
@Override
public boolean test(Object t) {
//集合中以1开头的元素删除
if (t.toString().startsWith("1")) {
return true;//删除
}
return false;//不删除
}
}
public static void main(String[] args) {
//创建集合对象
List alist=new ArrayList();
//向集合中添加对象
alist.add(11);//0
alist.add(22);//1
alist.add(33);
alist.add(14);
//遍历集合
for (Object ob : alist) {
System.out.println(ob);
}
//创建过滤器对象
MyFilter mf=new MyFilter();
//根据过滤器对象删除元素对象
alist.removeIf(mf);
System.out.println("--------------------");
//遍历集合
for (Object ob : alist) {
System.out.println(ob);
}
}
6.LinkedList:存储有序,可重复的单一对象.底层采用双向链表结构存值
优点:添加和删除元素效率高
缺点:遍历访问元素和修改元素效率低
后续补图
public static void main(String[] args) {
//创建集合对象
LinkedList alist=new LinkedList();
//向集合中添加对象
alist.add(11);//0
alist.add(22);//1
//向集合中指定索引处添加集合对象,0<=索引取值范围<=集合.size()
alist.add(0, 66);//0
//向集合中第一个和最后一个位置添加元素
//alist.addFirst(77);
//alist.addLast(88);
//遍历集合
for (Object ob : alist) {
System.out.println(ob);
}
System.out.println("--------------------");
//修改集合中指定索引处的元素对象,0<=索引的范围<集合.size()
alist.set(1, 77);
//遍历集合
for (int i = 0; i < alist.size(); i++) {
//得到集合中索引为i处的对象
System.out.println(alist.get(i));
}
System.out.println("*******************************");
//按照索引删除集合中元素对象,0<=索引的范围<集合.size()
alist.remove(1);
//按照元素对象删除
//alist.remove((Object)22);
//删除最后一个元素对象
//alist.removeLast();
//遍历集合
for (Object ob : alist) {
System.out.println(ob);
}
System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
//清空集合
alist.clear();
//遍历集合
for (Object ob : alist) {
System.out.println(ob);
}
}
7.跌代器(Iterator):遍历访问collection集合中每个元素
集合名.iterator();获得当前集合跌代器对象
跌代器对象.hasNext();判断跌代器对象后面是否有元素可跌代
跌代器对象.next();跌代元素(访问当前元素),
注意:集合中每个元素只能调用一次next()
public static void main(String[] args) {
//创建集合对象
List alist2=new ArrayList();
//向集合中添加元素对象
//创建一个学生对象
Student stu1=new Student("aa", 11);
alist2.add(stu1);
alist2.add(new Student("bb", 41));
alist2.add(new Student("cc", 31));
alist2.add(new Student("dd", 21));
//获得集合的跌代器
Iterator it2=alist2.iterator();
//判断跌代器后面是否有元素可跌代
while (it2.hasNext()) {
//获得当前的跌代元素
Student s=(Student) it2.next();
System.out.println(s.sname+","+s.sage);
}
}
8.Collections:collection集合家族工具类
9.泛型:将引用数据类型参数化.(将引用数据类型作为参数来传递).语法:<数据类型>
9.1:泛型集合:将数据类型作为集合的参数,集合中每个元素必须都是这个泛型的数据类型。
1:为什么要用泛型集合:因为普通集合,存数据时要频繁的装箱(什么类型的数据存到集合中都要封装成Object类型),取出数据时要频繁的拆箱(将元素转换原来的类型),使用不方法.所以想到用泛型集合可以减少频繁的装箱和拆箱。
2:泛型集合:一个集合中只能存同一种数据类型。
3:语法: 集合类型<数据类型> 集合名=new 集合类型<数据类型>;
public static void main(String[] args) {
//创建集合对象
List<Student> alist3=new ArrayList();
//向集合中添加元素
alist3.add(new Student("aa", 11));
alist3.add(new Student("bb", 31));
alist3.add(new Student("cc", 21));
//获得集合的跌代器对象
Iterator<Student> it1=alist3.iterator();
//判断跌代器
while (it1.hasNext()) {
Student s=it1.next();
System.out.println(s.sname+","+s.sage);
}
}
9.2:泛型跌代器:将数据类型作为迭代器的参数,迭代出来的每个元素是泛型的数据类型
1:泛型迭代器的作用:减少频繁的类型转换的问题。
2:语法:Iterator<数据类型> 跌代器对象名=集合名.iterator();
3:泛型跌代器与泛型集合是黄金搭挡,集合用什么数据类型作为泛型,泛型跌代器就用相同的数据类型作为泛型的数据类型。
public static void main(String[] args) {
//创建集合对象
List<Student> alist3=new ArrayList();
//向集合中添加元素
alist3.add(new Student("aa", 11));
alist3.add(new Student("bb", 31));
alist3.add(new Student("cc", 21));
//获得集合的跌代器对象
Iterator<Student> it1=alist3.iterator();
//判断跌代器
while (it1.hasNext()) {
Student s=it1.next();
System.out.println(s.sname+","+s.sage);
}
}
9.3:泛型类:将引用数据类型作为类的参数,传到类中
/**
* 泛型类,<T>代表任意数据类型的泛型
*/
public class Teacher<T>{
public String sname;
public Integer sage;
//用泛型作为变量数据类型
public T num;
}
public static void main(String[] args) {
//创建老师对象
Teacher<String> teacher1=new Teacher<>();
//用对象调用属性
teacher1.sname="张三";
teacher1.num="你好";
//创建老师对象
Teacher<Integer> teacher2=new Teacher<>();
//用对象调用属性
teacher2.sname="ls";
teacher2.num=11;
}
9.4:泛型方法:将数据类型作为参数传到方法中用
/**
* 普通类
*/
public class Fun {
/**
* 泛型方法
* @param count
*/
public <T> void show(T count) {
System.out.println("方法参数为:"+count);
}
}
public static void main(String[] args) {
//创建对象
Fun f1=new Fun();
//用对象调用泛型方法
f1.show("张三");
f1.show(11);
f1.show(true);
}
9.5:泛型属性不能与static或final一起使用
泛型类,泛型方法可以与static,final,abstract一起使用
9.6:受限泛型:
(1)<?>:表示任意类型
(2)<? extends T>:表示T类或者T类的子类
(3)<? super T>:表示T类或者T类的父类
10.ArrayList VS Vector
1:推出时间不同:Vector在jdk1.0时就推出;ArrayList在jdk1.2时推出的
2:内存使用效率不同:Vector每次扩容按原来2倍扩容;ArrayList每次扩容按原来1.5倍扩容
3:线程安全性和效率不同:Vector是线程安全的类,但是效率低;ArrayList是线程不安全的类,但是效率高
4:ArrayList所拥有的所有方法Vector都有,Vector还有自己独有的方法(独有的方法比较复杂)