javase day16

本文探讨了Java中的集合(Collection)接口及其子接口List和LinkedList的实现细节。ArrayList基于数组实现,适合查询,但增删效率低;LinkedList通过节点存储,增删高效但查询慢。同时,文章提供了ArrayList和LinkedList的自定义实现,并展示了相关操作如添加、删除、查找等方法的使用。
摘要由CSDN通过智能技术生成

异常复习:
在这里插入图片描述

集合(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 + "]";
		}
	
	
	
	
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值