java集合
- java集合就好比一个容器,可以用于存放数量不等的多个对象,可以保存具有映射关系地的关联数组,还可以保存多个对象的引用。
2)java集合分为三种体系:List、Set、Map
List: 存放的数据是有序的,可重复的
Set:存放的数据是无序,不可重复的
Map:存放的数据是具有映射关系的集合(键—值)
3)集合框架图(Collection 接口是 List、Set 和 Queue 接口的父接口)
此图片非原创
4)实现各个接口的集合
1,List接口:ArrayList、LinkedList、Vector、Stack实现了List接口。
ArrayList:内部通过数组实现,可以对元素进行快速的查找访问,但是由于数组大小有限当长度不够时需要扩容,就需要将数据复制到新的数组,而且进行添加或删除操作时,都需要对数组中的元素进行移动,代价太高,所以AyyayList适用于对数据进行查找、遍历的操作,不适用于插入和删除。
下面是自己使用数组实现的ArrayList:
package pm;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
public class MyArryList<T> {
private int count=0; //数组元素个数
private Object[] os; //数组
private int DEFAULT=5; //默认数组长度
public MyArryList() {
os=new Object[DEFAULT];
}
//添加元素
public boolean add(T t){
Object[] newOs; //用于存放添加后的元素
if((count+1)>os.length){ //判断数组长度是否够用---->不够--->扩容
int oldSize=os.length;
int newSize=os.length+(oldSize>>1);
// int newSize=os.length+2;
newOs=new Object[newSize];
//向新数组拷贝元素
System.arraycopy(os,0,newOs,0,oldSize);
//加入新添的元素
newOs[count]=t;
//覆盖原来的数组
os=newOs;
}else{ //数组够用,不用扩容
os[count]=t;
}
count++;
return true;
}
//显示集合元素
public void show(){
for(int i=0;i<os.length;i++){
System.out.println((T)os[i]);
}
}
//添加元素--按索引添加到相应的位置(索引值,元素值)
public boolean add(int index,T t){
Object[] newOs; //用于存放添加后的元素
if((count+1)>os.length){ //判断数组长度是否够用---->不够--->扩容
int oldSize=os.length;
//int newSize=os.length+(oldSize>>1); //容量变大为原来的1.5倍
int newSize=os.length+2;//容量加2
newOs=new Object[newSize];
}else{ //数组够用,不用扩容
newOs=new Object[os.length];
}
//向新数组拷贝元素
System.arraycopy(os,0,newOs,0,index);
System.arraycopy(os,index,newOs,index+1,count-index);
//加入新添的元素
newOs[index]=t;
//覆盖原来的数组
os=newOs;
count++;
return true;
}
//删除指定索引的元素
public boolean delete(int index){
Object[] newOs; //用于存放删除后的元素
int oldSize=os.length;
int newSize=os.length-1;
newOs=new Object[newSize];
if(index>0){
System.arraycopy(os,0,newOs,0,index);
System.arraycopy(os,index+1,newOs,index,count-index);
os=newOs;
}else if(index==0){
System.arraycopy(os,index+1,newOs,0,os.length-1);
os=newOs;
}else{
System.out.println("索引错误");
}
count--;
return true;
}
//删除最后一个元素开始的自定义长度
public boolean del_size(int index){
Object[] newOs; //用于存放删除后的元素
int oldSize=os.length;
int newSize=os.length-index; //修改删除后的容量
newOs=new Object[newSize];
System.arraycopy(os,0,newOs,0,count-index);
os=newOs;
count=count-index;
return true;
}
//获取list 里索引的对应元素
public T get(int index){
return (T)os[index];
}
}
2,LinkedList:是使用双向链表结构存储数据的,适用于动态的插入和删除,而不适用与随机访问,遍历的速度也偏慢。可以用作堆栈,队列,和双向队列来使用。
单链表的实现
package am;
import javax.jws.WebParam;
public class MyLinkList <T>{
//链表长度
private int size;
//链表头节点
private Node head;
//尾节点
private Node tail;
public class Node{
private T data;
private Node next;
public Node(T data,Node node){
this.data=data;
next=node;
}
public Node(){}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
public MyLinkList(){
head=null;
tail=null;
}
public MyLinkList(T ele){
head=new Node(ele,null);
tail=head;
size++;
}
//返回链表长度
public int length(){
return size;
}
//在指定位置插入数据
public void insert(int index,T ele){
//如果链表为空--->插入节点
if(size==0) add(ele);
//不为空--->在指定位置插入节点
else{
Node current=head;
for(int i=0;i<size;i++){
if(i==index-1 && index-1>=0){
Node node=new Node(ele,current.next);
current.next=node;
}
else if(index==0){
Node newNode=new Node(ele,head);
}
else{
current=current.next;
}
}
}
size++;
}
//删除指定位置数据
public void delete(int index){
if(size==-1) System.out.println("链表为空,不可删除了.");
else if(size==0 && index==size){
head=head.next;
size--;
}
else{
Node current=head;
for(int i = 0; i < size && current != null; i++, current = current.next){
if(i==index-1){
current.next=current.next.next;
size--;
}
}
}
}
//显示链表
public void show(){
Node current = new Node();
current=this.head;
for (int i = 0; i < size && current != null; i++, current = current.next) {
System.out.println(current.data);
}
}
//在链表尾部添加节点
public void add(T ele){
if(head==null){
head=new Node(ele,null);
tail=head;
}else{
Node newNode=new Node(ele,null);
tail.next=newNode;
tail=newNode;
}
size++;
}
//得到相应索引的节点
public Node get(int index){
if(index<0 || index >size-1) System.out.println("输入索引出错!");
else{
Node current=head;
for(int i=0;i<size && current!=null;i++,current=current.next){
if(i==index) return current;
}
}
return null;
}
}
栈
package homework;
import java.util.Arrays;
public class MyStack<T> {
private Object[] os;
private int DEFAULT_SIZE = 5;
private int count = 0;
public MyStack() {
this.os = new Object[DEFAULT_SIZE];
}
public void push(T t) {
if (count + 1 > DEFAULT_SIZE) {
os = Arrays.copyOf(os, os.length * 2);
}
os[count] = t;
count++;
}
public T pop() {
if (count == 0) {
System.out.println("栈为空");
return null;
}
T t1 = (T) os[count - 1];
os[count - 1] = null;
count--;
return t1;
}
public void empty(){
if(count==0){
System.out.println("栈为空");
}else
System.out.println("栈不为空");
}
public T peek(){
if(count==0){
System.out.println("栈为空");
}
T t1=(T)os[count-1];
return t1;
}
public T search(){
if(count==0){
System.out.println("栈为空");
}
T t1=(T)os[1];
return t1;
}
public void show(){
for (int i=0;i<count;i++){
System.out.print(os[i]+" ");
}
System.out.println(" ");
}
}
双向链表
package homework;
public class MyDoubleLinkList<T> {
private int size;
private Node head;
private Node tail;
public class Node{
private T data;
private Node pre;
private Node next;
public Node(T data,Node node1,Node node2) {
this.data = data;
pre=node1;
next=node2;
}
public Node() {
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public Node getPre() {
return pre;
}
public void setPre(Node pre) {
this.pre = pre;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
public MyDoubleLinkList(){
head=null;
tail=null;
}
public MyDoubleLinkList(T ele){
head=new Node(ele,null,null);
tail=head;
size++;
}//返回链表长度
public int size(){
return size;
}
public T getData(int i) {
T t= get(i).data;
return t;
}
//在链表末尾加入数据
public void add(T ele){
if(head==null){
head=new Node(ele,null,null);
tail=head;
}else{
Node node=new Node(ele,tail,null);
tail.next=node;
tail=node;
}
size++;
}
//判断链表是否为空
public boolean isEmpty(){
if(size==0) return true;
return false;
}
//获取相应索引的元素
public Node get(int index) {
if (index < 0 || index > size - 1) {
System.out.println("索引异常!");
} else {
Node current = new Node();
current = head;
for (int i = 0; i < size && current != null; i++, current = current.next) {
if (index == i)
return current;
}
}
return null;
}
//删除末尾元素
public void delete(){
if(size==0){
System.out.println("不可删除,链表为空!");
}else if(size>0){
tail.pre=tail;
tail=null;
}
else{
System.out.println("索引出错!");
}
size--;
}
//删除相应位置的元素
public void deleteN(int index){
if(index==0){
head=head.next;
}else if(index>0){
get(index).pre.next=get(index).next;
get(index).next.pre=get(index).pre;
}
else{
System.out.println("索引出错!");
}
size--;
}
//在相应索引处添加元素
public void insert(int index,T ele){
if(index==0){
Node node=new Node(ele,null,head);
head.pre=node;
head=node;
}else if(index>0){
Node node=new Node(ele,null,null);
get(index).pre.next=node;
node.pre=get(index).pre;
node.next= get(index);
get(index).pre=node;
}
else{
System.out.println("索引出错!");
}
size++;
}
//显示集合
public void show(){
Node current=new Node();
current=head;
for(int i=0;i<size && current!=null;i++,current=current.next){
System.out.println(current.data);
}
}
}
3、Vector集合:底层数据结构是使用数组实现的,操作和ArrayList一致,查询快,增删慢,内部线程安全,但是效率低。
4、ArrayList与LinkedList的区别
ArrayList是基于动态数组的数据结构,LinkedList是基于链表的数据结构
对于随机访问,遍历来说,ArrayList优于LinkedList,因为LinkedList需要不断通过获得当前节点得到下一节点,有点移动指针的感觉。
对于增删操作,LinkedList优于ArrayList,因为LinkedList直接可以删除当前节点或在一处插入节点,只需要修改节点的下一节点的指向就行,而ArrayList则需要对数组中的数据进行复制,或还需修改数组长度,比较浪费时间。
5)Itrator接口:用于遍历集合中的元素----->迭代器
里面的方法有:hasNext()、next()、remove()