Java面向对象编程——集合框架
学习Java语言,必须掌握Java集合类的使用。Java集合类时实现数据结构的容器,专门存储Java类的对象
集合框架的概念:
数据机构与算法时程序开发中非常重要的知识点,这些知识点可以有效地提高程序运行的速度和效率。Java集合类就是把数据结构和算法根据不同的需求进行实现,让陈鼓型元可以开发出可靠,稳定并高效的程序。
引入集合框架
面向对象语言对事务的体现都是以对象的形似,所以为了方便对多个对象的操作,就可以将对象进行存储,集合就是存储对象最常用的一种方式。
集合和之前的数组的区别
数组 | 集合 | |
---|---|---|
长度 | 长度是固定的 | 长度是可变的 |
存储对象 | 可以存储基本数据类型,也可以存储对象的引用 | 只能用于存储对象的引用 |
对象类性 | 对象必须时相同类型的数据 | 对象可以是不同类型的数据 |
从以上分析中可以看出,数组在处理一些问题时存在明显的缺陷,而集合完全弥补了数组的缺陷,它比数组更灵活耿实用,可大大提高软件的开发效率,并且不同的集合可使用与不同的场合。如果写程序时并不知道程序运行时会需要多少对象,或者需要更复杂的方式存储对象,可以考虑使用Java集合来解决问题
Java集合框架包含的内容
(1):集合框架是为了表示和操作集合而规定的一种统一的标准体系结构,由 三大块内容组成
1):接口:表示集合的抽象数据类型,比如 Collection、List 、Set、Map等
2):具体类:集合框架中接口的具体实现,如ArrayList等
3):算法:在一个实现了某个集合框架中的接口的对象身上完成某种有用的计算方法,如查找、排序等。
(2):接口还有两大根接口: Collection和Mao.Collection下又有三个分支:List、Set 和 Queue 。除此之外,还有为操作集合开发的两个工具类。
1):Collection :包含有关集合的静态方法
2):Arrays:包含了各种数组操作的静态方法
List接口
List接口继承了Collection接口,称为有序集合,可以精确控制列表中的每一个元素的插入位置。通过整数索引获取列表中的元素。List与匈奴出现重复的值。实现List接口的常用类有两个,分别是:ArrayList 和 LinkedList。
ArrayList集合类
ArrayList 支持可随需要而增长的动态数组,在Java数组中,长度是固定的,因此在数组被创建后,不能修改长度,这意味着开发者需要知道数组的长度。但在一般情况下,只有在运行时在知道数组长度。为了解决这个问题,Arratlist因此而生
数组中的每一个元素,都存储在内存单元中,并且元素之间紧密排列,既不能打乱元素的存储顺序,也不能跳过某个存储单元进行存储。底层是使用数组实现的,所以查询速度块,增删速度慢。
案例代码:
package list;import java.util.ArrayList;/**
* @version 1.0
* @author: jiazhihao
* @date: 2021-05-06 17:11
*///数组扩容的代码;/*private Object[] grow(int minCapacity) {
int oldCapacity = elementData.length;
if (oldCapacity > 0 || elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
int newCapacity = ArraysSupport.newLength(oldCapacity,
minCapacity - oldCapacity, *//* minimum growth *//*
oldCapacity >> 1 *//* preferred growth *//*);
return elementData = Arrays.copyOf(elementData, newCapacity);
} else {
return elementData = new Object[Math.max(DEFAULT_CAPACITY, minCapacity)];
}
}*///查询多用这个publicclassArraylistDemo01{publicstaticvoidmain(String[] args){
String[] array01=newString[10];
array01[0]="zhangsan";
array01[2]="wangwu";
array01[1]="lisi";
ArrayList<Object> list01=newArrayList<>(100);// 数组的方式实现的// 数组列表 初始值为10//initialCapacoty 初始值// private static final int DEFAULT_CAPACITY = 10;// DEFAULTCAPACITY_EMPTY_ELEMENTDATA 默认的容量//1:增加的操作
list01.add("zhangsan");
list01.add("lisi");
list01.add("wangwu");
System.out.println(list01);//2:删除
list01.remove(1);// remove 移除
System.out.println(list01);// 3:修改
String v=(String) list01.set(1,"xiaowu");//返回初始值
System.out.println(v);
System.out.println(list01);//4:查询for(Object L:list01){
System.out.println(L);}// 5:求长度
System.out.println(list01.size());// 6 清空/*list01.clear();
System.out.println(list01.size());
System.out.println(list01.isEmpty());// 判断是否为空*/// list01.subList() // 截取//7: addAll ()
ArrayList<Object> list02=newArrayList<>();
list02.add(111);
list02.add(222);
list01.addAll(1,list02);
System.out.println(list01);}}
LinkedList集合类:
LinkedList是Link(链表)的双像数据结构,也可以当作堆栈、队列、双端队列。链表是一种在物理上非连续、非顺序的数据结构,有若干个节点(node)组成。
单链表
点链表的每一个节点包含两部分,一部分是存放数据的变量data,另一部分是指向下一节点的指针next 。一级一级,单线传递。
privatestaticclassNode{int data;
Node next;}
双链表:
双链表比单链表稍微复杂一些,他的每一届点除了拥有data和next指针,还拥有指向前置节点的prev 指针
链表存储数据的时候,则采用了见缝插针的方式,可以通过作图看到链表的每一个节点,并非每个都是连续的,很多是分布在内存的不同位置,依靠next指针关联起来。这样可以灵活的有效地利用零散的碎片空间
package list;import java.awt.*;import java.util.ArrayList;import java.util.LinkedList;/**
* @version 1.0
* @author: jiazhihao
* @date: 2021-05-06 18:16
*///不需要查询用这个 增删改查用这个publicclassLinkedListDemo02{publicstaticvoidmain(String[] args){
LinkedList<Object> list01=newLinkedList<>();// 链表的方式实现的
System.out.println(list01.size());// 长度默认为0// 数组列表 初始值为10//1:增加的操作
list01.add("zhangsan");
list01.add("lisi");
list01.add("wangwu");
System.out.println(list01);//2:删除
list01.remove(1);// remove 移除
System.out.println(list01);// 3:修改
String v=(String) list01.set(1,"xiaowu");//返回初始值
System.out.println(v);
System.out.println(list01);//4:查询for(Object L:list01){
System.out.println(L);}// 5:求长度
System.out.println(list01.size());// 6 清空/*list01.clear();
System.out.println(list01.size());
System.out.println(list01.isEmpty());// 判断是否为空*/// list01.subList() // 截取//7: addAll ()
LinkedList<Object> list02=newLinkedList<>();
list02.add(111);
list02.add(222);
list01.addAll(1,list02);
System.out.println(list01);//将数据添加到末尾
list01.addLast(111);//将数据添加到开头
list01.addFirst(999);
System.out.println(list01);}}
Set接口
实现set接口的常用类中有HashSet和TreeSet。他们都可以容纳所有类型的对象,包括null,不允许重复,HashSet存储顺序为无序,TreeSet存储顺序为有序,排序后为升序。
注意Set没有get()方法
HashSet和TreeSet的区别:
(1):HashSet采用Hashtable(哈希表)存储结构,TreeSet采用二叉树(红黑树)的存储结构。
(2):HashSet添加速度块,查询速度快,删除速度快,但是存储的数据是无序的
(3):TreeSet有序(排序后的升序)查询速度比List块(按照内容查询)。但查询速度没有HsahSet块。
HashSet案例代码:
package set;import java.util.HashSet;/**
* @version 1.0
* @author: jiazhihao
* @date: 2021-05-08 09:15
*/publicclassHashSetDemo{publicstaticvoidmain(String[] args){
HashSet<String> set=newHashSet<>();// 钻石语法
set.add("111");
set.add("444");
set.add("333");
set.add("222");
set.add("aaa");
set.add("bbb");
set.add("小明");
set.add("小花");
set.add("xxx");
System.out.println(set);
set.remove("xxx");// 根据内容移除
System.out.println(set);int size= set.size();boolean empty= set.isEmpty();
System.out.println(size);
System.out.println(empty);
set.clear();//清除
System.out.println(set);}}
输出结果:
可以看到输出的内容没有按照输入时的顺序进行输出。
TreeSet案例代码:package set;import java.util.TreeSet;/**
* @version 1.0
* @author: jiazhihao
* @date: 2021-05-08 09:26
*/publicclassTreeSetDemo{publicstaticvoidmain(String[] args){
TreeSet<String> set=newTreeSet<>();
set.add("111");
set.add("222");
set.add("地理");
set.add("历史");
set.add("asdd");
set.add("ASDD");
System.out.println(set);}}
输出结果
输出的结果可以看到:数据是按照数字、大写字母、小写字母、汉字进行排序的,但是汉字相关的数据本身没有排序,
Map接口:
Map 是一种把键对象和值对象进行关联的容器, 而一个值对象又可以是一个Map, 依次类推,这样就可形成一个多级映射。
想想学习英语使用的词典软件,输入英文(key)后,软件会显示出对应的中文(value)。Map就是在内存中的这种结构。
Key(键):
和 set— 样,键对象不允许重复,这是为了保持查找结果的一致性。 如果有两个键对象一样, 那你想得到那个键对象所对应的值对象时就有问题了。
在使用过程中某个键所对应的值对象可能会发生变化, 这时会按照最后一次修改的值对象与键对应(就是key同一个key有多次值绑定,最后一个就会覆盖之前的)
可以使用 null 作为 Key
Value(值):
值对象没有唯一性的要求, 你可以将任意多个键都映射到一个值对象上, 这不会发生任何问题( 不过对使用却可能会造成不便, 你不知道你得到的到底是那一个键所对应的值对象,所以请不要这样做)
可以使用 null 作为 Value
Map 有两种比较常用的实现: HashMap 和 TreeMap
Map接口的实现类主要有HsahMap、TreeMao、HashSet、ConcurrentHashMap及Proprties等
(1)TreeSet是有序的,HsahMap和HsahTable是无序的。
(2)Hsahtable的方法是同步的,HsahMap的方法不是同步的
HsahMap是最常用的Map,他根据键的HsahCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HsahMap最多值允许一条记录的键位null(多条会覆盖)。
案例代码
package map;import java.util.HashMap;import java.util.Map;/**
* @version 1.0
* @author: jiazhihao
* @date: 2021-05-15 13:36
*/publicclassHashMap2{publicstaticvoidmain(String[] args){
Map map=newHashMap();
map.put("CCTV","中央电视台");
map.put("BTV","北京电视台");
map.put("CHNTV","河南电视台");
map.put("TVB","翡翠台");// 显示【CCTV】对应的中文名字
String tvValue=(String)map.get("CCTV");// 显示集合中元素个数
System.out.println("元素共有"+ map.size()+"个");//判断是否包含键【CCTV]
System.out.println("map中包含有CCTV的键吗?"+map.containsKey("CCTV"));// 分别显示键集、值集和键值对
System.out.println(map.keySet());
System.out.println(map.values());
System.out.println(map);// 清空map中的数据
map.clear();if(map.isEmpty()){
System.out.println("已清空map中的数据");}}}
输出结果