异常复习:
集合(Collection)
是一个长度可变且可以存储多个数据(对象)的容器
----泛型 用于指定集合元素的数据类型,只能是引用类型
int[]arr;arr的数据类型是数组类型,arr的元素是int类型
Collection c; c的数据类型是引用类型,c中的元素是String类型
集合存储基本数据类型 1 2 4 Integer in=1;in可以存储在集合中
Collection是集合的顶级接口
子接口:List、Set、Queue
List(列表):保证存储数据有序,额可以根据下标进行操作集合元素
实现类:ArrayList、LinkedList、Vector、Stack
ArrayList(顺序表)
底层是由数组来实行,默认数组的初始长度是10,根据底层右移运算进行扩容,每次在原来的基础上扩容一般 10 15 22 33 ,可以指定容量。查询效率高、增删元素效率低
LinkedList(链表)
底层是由节点(静态内部类)来进行存储元素的。底层内存不连续,不需要扩容,增删元素效率较高、查询元素效率较低
如果这个场景需要用到ArrayList或者LinkedList,增删和查询的操作概率相当,用哪个?LinkedList-----内存不连续,没有空间浪费,提高内存利用率
Vector(向量)
底层基于数组,扩容是基于三目运算符默认增加一倍,但是可以指定增量,如果增量不为0就可以按照增量进行数组的扩容。Java第一个集合类
collection方法探索
public class CollectionDemo1 {
public static void main(String[] args) {
//创建集合对象
Collection<String> c=new ArrayList<>();
//存储,添加元素
c.add("abc");
c.add("c");
c.add("cty");
c.add("123");
//删除
//没有要删除的元素就不做操作
//c.remove("abc");
//清空结合
//c.clear();
//判断参数是否在集合中
//System.out.println(c.contains("abc"));
//判断集合是否为空
//System.out.println(c.isEmpty());
//集合元素个数
//System.out.println(c.size());
//System.out.println(c);
//在转化的过程中指明要转换的数组元素类型
String[] ss=c.toArray(new String[0]);//数组类型对象
Object[] os=c.toArray();
//Object转成具体的元素数类型
for (Object object : os) {
String s=(String)object;
//System.out.println(s);
}
}
}
list方法探索
public class CollectionDemo2 {
public static void main(String[] args) {
//创建列表集合对象
List<String> list=new ArrayList<>();
//添加元素
list.add("bv");
list.add("abc");
list.add("dsf");
list.add("123");
//插入元素----添加元素
//list.add(4,"ttt");
//根据元素进行删除
//list.remove("bv");
//根据下标进行删除
//list.remove(0);
//根据下标返回元素
//System.out.println(list.get(0));
//返回元素第一次出现的下标
//System.out.println(list.indexOf("123"));
//替换
/*
* list.remove(0); list.add(0, "123");
*/
//替换
list.set(0, "123");
//返回的是子列表
System.out.println(list.subList(2, 3));
System.out.println(list);
}
}
练习:
1、用数组实现ArrayList
package cn.tedu.list;
import java.util.Arrays;
/**
* @author 作者:
* @version 创建时间:2020年10月7日下午4:01:31
* @description 描述:利用数组实现ArrayList
*/
public abstract class ListText1 {
public static void main(String[] args) {
ListArray list=new ListArray();
/*
* list.add("123"); list.add("dfs"); list.add("vbng");
*/
System.out.println(list);
}
}
class ListArray {
// 存储数据的数组
String[] data;
// 数组中的元素个数以及数组的下标
int size = 0;
// 无参构造
public ListArray() {
// 默认初始长度为10
data = new String[10];
}
// 有参构造----指定初始容量
public ListArray(int initCapcity) {
data = new String[initCapcity];
}
// 数组的扩容
public void grow() {
// 在原来的基础上加上一半
if (data.length >= 2) {
data = Arrays.copyOf(data, data.length + (data.length >> 1));
} else {
data = Arrays.copyOf(data, data.length + 1);
}
}
//下标是否越界
public void out(int index) {
//如果下标越界就输出异常
if(index<0||index>=size) {
throw new IllegalArgumentException("index:"+index);
}
}
// 添加元素
public void add(String str) {
// 判断是否要扩容
if (size >= data.length) {
grow();
}
// 往数组里添加元素
data[size++] = str;
}
// 插入元素
public void add(int index, String str) {
// 判断下标是否越界
if (index < 0 || index > size) {// 下标数和元素数进行比较
throw new IllegalArgumentException("index:" + index);
}
//
// 判断是否要扩容
if (size >= data.length) {
grow();
}
/*
* // 依次把index后面的数组元素往后赋值 for (int i = size - 1; i >= index; i--) { data[i + 1]
* = data[i]; }
*/
//
System.arraycopy(data, index, data, index+1, size-index);
//插入这个元素
data[index] = str;
//元素个数
size++;
}
//根据下标删除
public void remove(int index) {
//判断下标是否越界
out(index);
//依次把index后面的数组元素往前赋值
/*
* for (int i =index+1; i < size; i++) { data[i-1]=data[i]; }
*/
System.arraycopy(data, index+1, data, index, size-(index+1));
size--;
}
//返回元素第一次出现的下标值
public int indexOf(String str) {
//遍历数组依次比较
for (int i = 0; i < size; i++) {//只比元素
//判断是否相等
if(str==data[i]||str!=null&&str.equals(data[i])) {
//返回下标值,结束
return i;
}
}
//数组中没有出现
return -1;
}
//根据元素删除
public void remove(String str) {
//返回结果值
int index=indexOf(str);
//判断返回值是否为-1
if(index!=-1) {
remove(index);
}
}
//清空结合
public void clear() {
size=0;//没有可以遍历的元素
}
//判断是否包含元素
public boolean contains(String str) {
//
/*
* if(indexOf(str)!=-1) { return true; } return false;
*/
return indexOf(str)!=-1;
}
//获取元素
public String get(int index) {
//越界问题
out(index);
//返回指定元素
return data[index];
}
//判断集合是否为空
public boolean isEmpty() {
return size==0;
}
//替换元素
public void set(int index,String str) {
//是否越界
out(index);
//替换
data[index]=str;
}
//返回元素个数
public int size() {
return size;
}
//截取一个子列表
public ListArray subList(int fromindex,int toindex) {
//越界问题
out(fromindex);
//越界问题
out(toindex);
//判断下标大小是否正确
if(fromindex>toindex) {
throw new IllegalArgumentException("FromIndex:"+fromindex+",ToIndex:"+toindex);
}
//新建列表
//指定新列表长度
int count=toindex-fromindex;
ListArray l=new ListArray(count);
//数组的复制
System.arraycopy(data, fromindex, l.data, 0, toindex-fromindex);
//赋值size-----把复制的元素个数赋值给新列表的size
l.size=count;
//返回新列表
return l;
}
//重写toString方法
//输出对象的时候输出的是元素
@Override
public String toString() {
//创建StringBuilder的对象
StringBuilder sb=new StringBuilder("[");
//拼接字符串数组中的元素
for (int i = 0; i < size; i++) {//只遍历有元素的下标
//拼接元素
sb.append(data[i]).append(", ");
}
//转成字符串
String s=sb.toString();
//截取字符串,后面的不要了
//判断size是否大于0
if(size>0) {
s=s.substring(0, s.length()-2);
}
/*String s="[";
if(size!=0) {
for (int i = 0; i < size; i++) {
s+=data[i]+", ";
}}*/
return s+"]";
}
}
LinkedList的实现
package cn.tedu.list;
/**
*@author 作者:
*@version 创建时间:2020年10月8日下午2:52:46
*@description 描述:实现LinkedList
*/
public class ListText2 {
public static void main(String[] args) {
ListLinked list=new ListLinked();
list.add(null);
list.add(null);
list.add("rrt");
list.add("ccc");
list.add("huj");
list.add("zzz");
System.out.println(list);
System.out.println(list.indexOf(""));
}
}
//实现LinkedList
class ListLinked{
//元素个数/节点数
int size=0;
//头节点----表示第一个节点
Node first;
//尾节点----表示最后一个节点
Node last;
//节点----内部类
class Node{
//存储元素
String item;
//上一个节点
Node prev;
//下一个节点
Node next;
//有参构造
public Node(String item,Node prev,Node next ) {//元素给节点赋值
this.item=item;
this.prev=prev;
this.next=next;
}
}
// 下标越界问题
public void out(int index) {
if (index < 0 || index >= size) {
throw new IllegalArgumentException("index:" + index);
}
}
//根据下标找节点
public Node getNode(int index) {
Node no=this.first;
for (int i = 0; i < index; i++) {
no=no.next;
}
return no;
}
// 添加
public void add(String str) {
// 新节点
Node node = new Node(str, null, null);
// 判断添加元素的位置
if (size == 0) {// 表明添加的是第一个节点
// 头节点指向新节点
this.first = node;
/*
* // 尾节点指向新节点 this.last = node;
*/
} else {// 尾部添加
// 原尾节点的下一个指向新节点
this.last.next = node;
// 新节点的上一个指向原尾节点
node.prev = this.last;
/*
* //尾节点指向新节点 this.last=node;
*/
}
// 尾节点指向新节点
this.last = node;
// 节点个数加1
size++;
}
//插入节点
public void add(int index,String str) {
//下标越界问题
if(index<0||index>size) {
throw new IllegalArgumentException("index:"+index);
}
//判断加入节点的位置
//插入的节点位置是头节点且size为0
//在尾部进行添加节点
if(index==size) {//尾部添加,头部添加
add(str);
//结束方法
//保证size不会添加两次
return;
}
//新节点
Node node=new Node(str, null, null);
//size不为0
if(index==0) {
//原头节点的上一个指向新节点
this.first.prev=node;
//新节点的下一个指向原头节点
node.next=this.first;
//头节点指向新节点
this.first=node;
}else {//表明在中间插入
//获取标明下标的节点
Node no=this.first;
for (int i = 0; i < index; i++) {
no=no.next;
}
//no节点的上一个节点的下一个指向新节点
no.prev.next=node;
//新节点的上一个指向no节点的上一个节点
node.prev=no.prev;
//no节点的上一个指向新节点
no.prev=node;
//新节点的下一个指向no
node.next=no;
}
//
size++;
}
//删除-----根据下标
public void remove(int index) {
//下标越界问题
out(index);
//判断删除节点的位置
//判断是否删除的头节点
if(index==0) {
//原头节点的下一个节点的上一个为null
this.first.next.prev=null;
//头节点指向原头节点的下一个节点
this.first=this.first.next;
}else if(index==size-1){//尾部删除
//原尾节点的上一个节点的下一个为null
this.last.prev.next=null;
//尾节点指向原尾节点的上一个节点
this.last=this.last.prev;
}else {
//删除中间节点
//获取指定节点
Node no=getNode(index);
//no的下一个节点的上一个指向no的上一个节点
no.next.prev=no.prev;
//no节点的上一个节点的下一个指向no的下一个节点
no.prev.next=no.next;
}
//
size--;
}
//元素第一次出现的下标
public int indexOf(String str) {
//遍历节点找出满足要求的节点
Node node=this.first;
for (int i = 0; i < size; i++) {
//把每个节点的元素和参数进行比较
if(str==node.item||str!=null&&str.equals(node.item)) {
//if(str==node.item||node.item!=null&&str.equals(node.item)) {
return i;
}
node=node.next;//下一个节点
}
//没有找到
return -1;
}
//根据指定元素进行删除
public void remove(String str) {
//获取下标
int index=indexOf(str);
//判断是否为-1
if(index!=-1) {
remove(index);
}
}
//重写String
@Override
public String toString() {
// 创建对象
StringBuilder sb = new StringBuilder("[");
// 拼接节点里的元素
// 遍历节点
Node no = this.first;
for (int i = 0; i < size; i++) {
sb.append(no.item).append(", ");
no = no.next;// 下一个节点
}
String s = sb.toString();
if (size > 0) {
s = s.substring(0, s.length() - 2);
}
return s + "]";
}
}