我们先来谈谈数组:
一 数组的常识:
数组的本质---数组本质上并不是指里面保存的数据,而是保存这些数据的的位置,也就是保存这些数据的内存空间
数组封装---字面量,变量,常量
数组的目的就是对数据快速的增删改查
数组的内存内部结构 : 物理空间上是一段连续挨着的内存空间,同时给他们的标号也是从0开始的自然数
数组的数据类型 : 应用数据类型
数组是Java内置的对象,而Array和Collection只是工具对象,用来方便操作数组和集合的
特殊的数据类型,没有在任何包中,所以不需要导包.,java.util.Arrays只是一个操作类,是操作数组的工具类,使用工具类中工具的时候,需要导包.
1 数组是一种引用数据类型
2 数组也是一种线性的数据结构(对应的就是表)
3 数组是一个容器(后面会专门学到容器),用来存储其他的元素
数据可以存储任意类型的元素
4 数组按照层数分类:一维数组,二维数组,三维数组,多维数组......;(,每个都是不同的数据类型)
5 单个数组中,存储的元素的数据类型必须是同一种类型
6 数组的长度不能直接改变,也就是说,数组里面元素的个数是不能再原数组上直接改变的:数组为保存数据划分的内存空间个数和每个空间的长度不能改变
二 数据的基本理论
创建数组的三个步骤---声明,初始化,赋值
数组里面的的内存空间怎么访问的?是通过下标访问的
数组的特性:
1 每个单独数组中的元素的数据类型必须是统一的,数据类型统一,也就意味着每个数据在内存中占据的空间大小是一样
2 数组是引用数据类型,在栈内存中,索引保存的是数组对象第一个元素的内存地址,数组用第一个元素的地址作为数组对象的内存地址.同时在数组声明的时候,会有一个length的默认元素用来保存数组元素的个数.要查找某个元素,只需要首内存地址加上偏移量即可(通过首内存地址,加上偏移量,快速计算出要查找元素的内存地址,从而取得元素).通过内存地址直接查找,所以效率比较高
3 数组对于数据处理:查找,更改,效率较高,但是增删效率较低;因为增删要保证元素的有序,该元素以后的都要进行向前移位或者向后移位操作
三 数组排序 ---系统方法排序
---冒泡排序:
1 参与运算的元素: 两个元素,及其下标,一个临时变量,5个
2 外层循环定位第一个元素,然后在内层循环分别和第一个元素后面的每个进行比较一遍,然后小的和第一个元素进行交换,当交换完以后,循环结束(重点:并没有循环到最后一个元素,只是循环到了,满足条件的地方);这个元素就变成了a[i],也就是变成了第一个元素,然后进行第二次内层循环,但是这次会从那个交换位置的下标加一的位置开始匹配(因为交换完,j进行了加一),匹配完,再从第二位开始挨个匹配,依次类推;
---选择排序:
每次都把集合内最小元素放到最左边
参与运算的元素:两个元素,及其下标,一个临时变量,一个下标临时变量
步骤:声明一个临时下标变量,先把最左边下标赋值给他,然后在剩下的元素中找最小值元素的下标,把这个下标赋值给那个临时下标变量
然后,把最左边的元素和这个临时下标变量对应的元素交换位置;依次类推
相对于冒泡的优点:内层查找一遍完成后,在交换依次
冒泡是:查找一次,交换一次
节省了交换效率
---相对冒泡的优点:内层查找一篇完成后,在交换依次冒泡是:查找依次,交换依次
四 数组遍历:
for(int i=0;i lt length-1;i++)
for(数据类型 e : 数组索引变量);
五 二分查找
1 二分法查找是建立在已经排序的基础之上的
2 数据里面没有重复的元素
二分查找算法实现:
1 确定数据的开始位置和结束位置
2 然后确定数据的中间位置数据,判断中间位置数据是否为目标数据,如果是,直接返回该数据
3 如果不是:看数据和中间位置数据的大小,如果大于,则一中间数据位置加一为界,查找后半段中间位置数据是否为目标数据
4 以此为界,递归或者循环
六:二维数组
1 二维数组,是特殊的一维数组;每个元素都是个一维数组而已
2 二维数组的初始化
静态初始化 int[][] 变量名 = {}
动态初始化 int[][] 变量名 = new int[3][4]
3 获取二维数组的元素:先定位外层下标,再定位内层下标,层层递进
4 遍历二维数组,双层for循环
5 函数调用 二维数组的传递
传引用或直接在实参处声
七 数组模拟栈
栈的特点:后进先出,压,弹,像弹夹一样
一个压栈方法:push
一个弹栈方法:pop
索引数组与关联数组图
----------------------------------
下面我们来谈谈集合:
一 集合的原理:
对象:数据和逻辑封装的一种形式
程序就两种组成元素:数据和逻辑
容器:本质是抽象数据在内存中的管理方式
对象:每个对象都有hashCode()方法,这个方法用于生成对象在内存中的逻辑地址,这就相当于对象的索引,每个对象也有equals方法;对象相等要每次生成的hash码必须相等
什么是容器:javaAPI提供的一系列的类的实例,用于在程序中存放对象;大小不固定的类;1136(一个图,一个类,三个知识点,6个接口)
二 集合在java.util包:
多态的密集应用;最大的灵活性:指针,一用用上级接口,对象用最下面的对象;调用的方法,还是上级的方法;指向的对象就可以随便换
只能添加对象;不能添加基本数据类型;栈里面的会随时被清空
三 Collection(集合)
1:只装值,不需要小标,小标默认,equals()
2:Collection c = new HashSet();
3:方法();
boolean isEmpty():是否为空
int size():元素个数
boolean contains(Object element):是否包含某对象
void clear():清空
boolean add(Object element):添加厶对象
boolean remove(Object element):删除某元素
Iterator iterator():迭代器,遍历出所有的元素
boolean containAll(Collection c):两个结合元素是否一样
boolean addAll(Collection c):同时忘集合中添加多个对象
boolean remove(Collection c):同时删除多个元素
boolean retainAll(Collection c):两个集中都有的对象
Object[] toArray():集合变成数组
4:集合set(无序,不重复,没有默认下标)HashSet:塑料袋,(hashcode下标),本质是hashMap,没有了key
5:集合list(有序,可重复,有默认下标)
它的方法():
Object get(int index);
Object get(int index, Pbject element);返回旧元素
Void add(int index, Object element);
Object remove(int index);
int indexOf(Object o);
int lastIndexOf(Object o);'
6:集合Map---自定义下标,自定义值:key=>value(键也是一个对象)
---HashMap/TreeMap:就相当于中药柜子
键不能重复;具体操作是挨个的equals,但是这样太慢,所以Map给每个键生成了一个HashCode存放在HashTable中,每次比较的是hash码,把比较对象的键调用HashCode()函数生成HashCode,再去HashTable中比较就快多了;本质就是缓存的思想
---Map方法()
Object put(Object key, Object Value);
Object get(Object key);
Object remove(Object key);
Object containsKey(Object key);
Object ContainsValue(Object Value);
int size()
boolean isEmpty()
void putAll(Map t);
void clear()
7:集合操作---普通迭代遍历:for/while
---Iterator
迭代器:用于挨个取出容器中的元素,每个集合都是先了这个,都有iterator()方法,就认为是一个指针,游标.
hasNext():是否有下一个元素
next():拿出下一个元素
remove():删除元素
---增强for循环
for(集合中元素的类型 对象变量 : 集合)
其内部调用的还是Iterator;删除还是要用Iterator的删除
8:泛型---泛型是个继承体系,和异常差不多,如果父类,系统类打了标签,你就必须打标签(接口)
---泛型的本质还是数据类型
基础数据类型自动转换
基础数据类型强制转换
自动数据类型转换
强制数据类型转换
装箱/拆箱
集合总结:可以用1136来表示---一个图
---一个类:Collections
---三个知识点:For,Generic,boxing
---六个接口
Collection
Map
Set
List
Iterator
Compare