最基本两个容器:变量、数组----变量是最小的数组
**集合:**可以存储多个数据(对象)且长度可变的容器
java.util 接口 Collection–>E代表泛型–>泛型表示集合的元素类型
由于集合泛型的指定:
集合的类型只能是引用数据类型
int []arr;//arr的类型是数组类型(引用类型),元素类型是int类型
Collection c;//c的类型是接口类型(引用类型),元素类型是String类型
Collection是所有集合的顶级接口 List Set Queue,Iterrator不是集合的接口
List—>中文名(列表)
保证数据存放有序;可以存储重复元素;可以通过下标来操作元素;线程不安全的集合
**实现类:****ArrayList ,LinkList, Vector ,(常用)**
ArrayList:默认的初始容量为10;也可以进行指定通过构造方法
1. 底层由数组实现数据存储,默认初始容量为10
2. 底层通过右移运算(<<1)进行扩容每次扩容是在原容量的基础上的一半进行扩容
变量,数组元素支持所有的数据类型
LinkedList (链表)
底层基于节点(静态内部类)来存储数据,通过地址值的指向地址空间,
维系节点的,内存不连续,不需要扩容,增删效率较高,查询效率低,线程不安全的集合
底层实现有三大属性进行实现的结果:通过引用类型的Node进行指向,E--表示的存储的数据类型
transient Node<E> first;
transient Node<E> next;
transient Node<E> last;
Vector(向量)
a.最早的集合类 1.0开始
b. 底层基于数组实现数据存储,默认初始容量事10
c.底层根据三目运算符进行扩容,如果增量值大于0,每次扩容的值就是增量的值,如果增量不大于0每次扩容的增量就是原来容量的值
d.是线程安全的集合
Vector的子类---->Stack(栈结构)—EmptyStatckException
a.遵循先进后出原则
b.栈顶元素
c.栈底元素
d.压栈/入栈
e.出栈/弹栈
继承自Vector类
迭代器(Iterator接口)
a.底层根据指针挪到进行迭代遍历
b.遍历期间不能使用集合本身的方法remove进行删除
c.iterator方法定义在iterable里面
d.类实现iterable接口产生的对象就能被增强来进行操作–增强for循环底层由迭代器实现–增强for循环是jdk1.5新特性
e.Collection是所有集合的顶级父类,所以iterable与集合无关
底层通过使用标记值的方式进行配对数组中的值进行配对,但是iterrator不会保证元素的顺序的效果执行,长度的标记是一样的指定,比如 底层的代码:hasnext方法的实现---》return cursor != size;(size代表的是数组的集合的元素个数,cursor表示的是当前元素的下一个索引位置),一旦使用集合的方法改变集合中的元素的结构,那么将不会再次进行对应。
自定一实现:ArrayList的----数组的扩容:Arrays.copyof(sorArray,newLength)赋值到原来的数组引用:
import java.util.Arrays;
public class TestArrayList {
//用数组实现ArrayList--->自定义实现ArrayList的底层进行是实现
public static void main(String[] args) {
//测试
ListArray list=new ListArray();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
//list.clear();
System.out.println(list);
list.set(1,"45");
System.out.println("C:"+list.indexOf("c"));
System.out.println("a:"+list.get(1));
System.out.println(list.contains("45"));
System.out.println(list.get(6));
System.out.println(list);
}
}
//实现ArrayList
class ListArray{
//声明数组存储元素
String[] data;
//定义变量定义数组下标---代表元素个数
int size=0;
//无参构造---默认初始长度
public ListArray(){
data=new String[10];
}
//有参构造---指定初始容量
public ListArray(int initCapacity){
data = new String[initCapacity];
}
//扩容方法
public void grow(){
if (data.length<=1){
data=Arrays.copyOf(data,data.length+1);
}
data= Arrays.copyOf(data,data.length+(data.length)>>1);
}
//添加元素
public void add(String str){
//判断是否需要扩容
if (size>=data.length){
grow();
}
data[size++]=str;
}
//clear()清空集合
public void clear(){
//让size的个数为0
size=0;
}
//判断是否包含一个元素
public boolean contains(String str){
return indexOf(str)!=-1;
}
//indexof()返回第一个值的下标索引
public int indexOf(String str){
//进行数组的遍历
for (int i = 0; i < data.length; i++) {
//date[i]==str---代表的是比较的是地址值是否相等,字符串常量池中的引用值是否是同一个-
//地址分为校验两部分 有地址指向和没有地址指向--null和有地址指向的问题
//str1=null--->保证str传递过来的地址不是空地址,空地址,不指向任何地址内存
if (data[i]==str||str!=null&&str.equals(data[i])){
return i;
}
}
return -1;
}
//判断下标是否越界问题
public String get(int index){
//判断下表是否越界
isOut(index);
return data[index++];
}
//判断是否是空集合
public boolean isEmpty(){
return size==0;
}
//替换元素 set(int index,String str)
public void set(int index,String str){
//判断下表越界
isOut(index);
//将对应内容赋值为指定内容
data[index]=str;
}
//抽取的方法---进行判断数组下标是否越界
private void isOut(int index) {
//数组的下标和size有关,size表示的元素的个数
if (index>size-1||index<0){
throw new IndexOutOfBoundsException("Arrays is IndexOutOfBOundsException");
}
}
//返回集合的元素个数
public int size(){
return size;
}
//截取子列表
public ListArray subList(int fromIndex,int toIndex){
//下表越界问题
isOut(fromIndex);
isOut(toIndex);
//保证起始下标小于等于结束下标
if (fromIndex<toIndex){
throw new IllegalArgumentException("fromIndex"+fromIndex+":toIndex"+toIndex);
}
//截取的元素个数
int count=toIndex-fromIndex;
//新建列表对象接收截取的元素
ListArray list = new ListArray(count);
//将数组里内容复制到新列表对象的新数组当中---list.data(将data进行赋值的调用,data是lsit的属性)
System.arraycopy(data,fromIndex,list.data,0,count);
//给新列表对象的size进行赋值
list.size=count;
//返回子列表
return list;
}
//重写toString方法
public String toString(){
//提供一个StringBuidler类的对象
StringBuilder sb=new StringBuilder("[");
//遍历数组元素
for (int i = 0; i < size; i++) {
sb.append(data[i]).append(", ");
}
//转成string类型
String s = sb.toString();
//System.out.println(s);
//去掉最后两个字符
if (size>0)
s=s.substring(0,s.length()-2);
//返回拼接结果
return s+"]";
}
}
自定义实现LinkedList链表部分:
public class LinkedListDemo2 {
public static void main(String[] args) {
//自定义链表的实现---》LinkedList
//测试
LinkList link=new LinkList();
link.add("a");
link.add("b");
link.add("c");
link.add("d");
System.out.println(link.size());//通过
System.out.println(link);//通过
System.out.println(link.get(1));//通过
//link.clear();//通过
System.out.println(link);//通过
System.out.println(link.remove());//通过
System.out.println(link);//通过
}
}
//定义自定义链表
class LinkList{
//定义元素的个数
private int size=0;
//指定链表的第一个节点
Node1 head=null;
//指定链表的最后一个节点
Node1 last=null;
//方法---》返回链表中的元素个数---size()
public int size(){
return size;
}
//方法--->向链表中添加数据---》add(String str)尾插法
public void add(String str){
//创建新的节点
Node1 newNode1=new Node1(str);
//判断链表是否为空链表
if(head==null){
//第一个节点为head节点,最后一个节点也是第一个节点
//数据域存进去
newNode1.str=str;
head=newNode1;
last=newNode1;
size++;
return;
}
//head不为null的情况下--第一个节点指向的第二个新创建的节点
last.next=newNode1;
//存储数据域
newNode1.str=str;
//新节点的下一个为null
newNode1.next=null;
//存储完数据域之后进行节点的存储--保证新的节点一定进行为最后一个节点
last=newNode1;
size++;
}
//方法--->删除链表中的元素---》remove()获取并移除此列表的头(第一个元素)。
public String remove(){
//移除第一个元素,判断链表是否为空
if (head==null){
//空链表抛出异常---空表
throw new EmptyStackException();
}
//链表不为空的情况下
//头节点等于第二个节点
String s=head.str;//获取的是第一个节点中的数据域---进行暂存处理
head=head.next;//头节点的下一个节点指向自己
size--;
return s;
}
//方法--->清除链表中的数据---clear()
public void clear(){
size=0;
}
//方法--->获取方法中的指定位置的元素--->get(int index)
public String get(int index){
//判断链表是否是空表
if (size==0){
//没找到,或者不存在
return null;
}
int count=0;
String s=null;
//遍历链表的数组,从头开始进行遍历执行
Node1 temp=head;
while(temp!=null){
count++;
//循环遍历的条件
temp=temp.next;
if (count==index){
//进行遍历执行
s=temp.str;
}
}
return s;
}
//方法---》获取元素数组的数组形式的数据---》toString()
public String toString(){
StringBuilder sb=new StringBuilder("[");
//进行数组的遍历进行添加元素
if (size==0){
//空链表
return sb.append("]").toString();
}
String []str=new String[size];
int index=0;
Node1 temp=head;
//不为空的情况
while(temp!=null){
str[index++]=temp.str;
temp=temp.next;
}
//去掉最后的两个字符
return Arrays.toString(str);
}
}
//定义链表的节点属性
class Node1{
public String str;
//最后的节点
Node1 last;
//代表下一个的指针
Node1 next;
//构建构造方法进行传递值---》存取的是数据域的值
public Node1(String str){
this.str=str;
}
}
自定义实现栈的结构存储结构:
public class StatckTest {
public static void main(String[] args) {
//使用数组模拟栈的实现
Stack stack = new Stack();
stack.push("a");
stack.push("b");
stack.push("c");
stack.push("d");
stack.push("e");
System.out.println(stack);
System.out.println(stack.peek());
System.out.println(stack.empty());
System.out.println(stack.pop("b"));
System.out.println(stack.search("e"));
System.out.println(stack.size());
}
}
class Stack{
//栈中的元素个数--全局变量
private int size=0;
String []data;
//栈的构造方法,设定初始长度
public Stack(){
data=new String[10];
}
public int size(){
return size;
}
//添加方法push()
public String push(String str){
//进行空间的判断,元素的个数大于原本给定的空间的大小,进行扩容
if (size>=str.length())
grow();
//空间自动进行扩容后,添加元素在数组中
return data[size++]=str;
}
//扩容数组
public void grow(){
data=Arrays.copyOf(data,data.length+(data.length)>>1);
}
public boolean empty(){
return size==0;
}
//获取栈顶元素
public String peek(){
if (empty())
throw new EmptyStackException();
return data[size-1];
}
//删除方法 pop()---删除栈顶元素
public String pop(String str){
//如果是空栈的话直接抛出空栈异常
if (empty()){
//抛出空栈的异常
throw new EmptyStackException();
}
//不是空栈的情况,进行栈中的元素的对比
for (int i = 0; i < data.length; i++) {
//获取栈顶元素
String s=peek();
if (data[i]==s||data[i]!=null&&data[i].equals(s)){
size--;
return data[i];
}
}
return null;
}
//查找并返回元素在堆中的位置
public int search(String s){
//从栈顶元素开始查找
for (int i = size-1; i <=0 ; i--) {
if (data[i]==s||data[i]!=null&&data[i].equals(s)){
//当找到的时候进行输出
return size-i;
}
}
//表示的没有找到该元素,直接直接掉
return -1;
}
//重写toString方法
public String toString(){
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < data.length; i++) {
sb.append(data[i]).append(", ");
}
//转成字符串
String s = sb.toString();
//进行字符串的切割
s = s.substring(0, data.length - 2);
return s+"]";
}
}
`
**Set(散列表)**无序,不能存储重复元素-----》请看下集分享
实现类:HashSet LinkedHashSet TreeSet