ArrayList,LinkedList,HashSet,HashMap(熟悉和理解容器,手动写一些简单的容器)

ArrayList

import java.util.ArrayList;

public class myArrayList<E> {
	private Object[] elementDate;
	private int size;
	private static final  int DEFAULT_CAPACITY=10;//默认数组的容量
	
	//构造器
	public myArrayList() {
		elementDate=new Object[DEFAULT_CAPACITY];
	}
	public myArrayList(int capacity) {
		elementDate=new Object[capacity];
	}
	
	//增加元素,需要进行扩容
	public void add(E element) {
		//当放入的元素个数size与数组的长度相等时,需要进行扩容
		if(size==elementDate.length) {
			Object newArray=new Object[elementDate.length+(elementDate.length>>1)];//15
			//增加原数组的个数
			System.arraycopy(elementDate,0,newArray, 0, elementDate.length);
			elementDate = (Object[]) newArray;
		}
		
		
		elementDate[size++]=element;
	}
	
	
	//重写toString方法
	public String toString() {
		StringBuilder s=new StringBuilder();
		s.append("[");
		for(int i=0;i<size;i++) {
			s.append(elementDate[i]+",");
		}
		s.setCharAt(s.length()-1, ']');
		return s.toString();
	}
	
	//增加set和get方法,
	public E get(int index) {
		checkRange(index);
		return (E)elementDate[index];
	}

	public void set(E element,int index) {
		//检查索引的范围[0,sise)
		checkRange(index);
		elementDate[index]=element;
	}
	
	
	
	//除了在set get方法中需要对索引进行判断外,在很多的方法中都需要对其进行判断
	//因此我们将其封装成一个方法
	public void checkRange(int index) {
		if(index<0||index>size-1) {
			//不合法
			throw new RuntimeException("索引不合法"+index);//手动抛出一个异常
		}
	}
	
	//增加remove方法
	public void remove(E element) {
		//element和他们所有的元素进行比较,获得第一个比较为true的,返回。
		for(int i=0;i<size;i++) {
			if(element.equals(get(i))) {//容器中所有的比较操作,都用的是equal方法
				//将该元素从此处移除
				remove(i);
			}
		}
		
	}
	
	
	public void remove(int index) {
		//本质就是数组的拷贝
		int move=elementDate.length -index-1;
		if(move>0) {
			System.arraycopy(elementDate, index+1, elementDate, index,move);
	
		}
		//若删除的最后一个元素
			elementDate[size-1]=null;
			size--;
		
		
		
	}
	
	//返回size的方法
	public int size() {
		return size;
	}
	
	//判断为空的方法
	public boolean isEmpty() {
		if(size==0)
			return true;
		return false;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		myArrayList m=new myArrayList(20);
		for(int i=0;i<30;i++) {
			m.add(" "+i);
		}
		System.out.println(m);
		System.out.println(m.get(10));
		m.set("q",10);
		System.out.println(m.get(10));
		
		m.remove(3);
		System.out.println(m);
		System.out.println(m.size);
		System.out.println(m.isEmpty());
	}
	

}

LinkedList

/**
 * 底层实现的是用链表的增删效率高,查找效率低
 * 
 * @author lsy
 *
 */
public class myLinkedList<E> {
	//通过第一个和最后一个结点对该链表进行操作,增加或者删除元素
	private Node first;//第一个结点
	private Node last;//第一个结点
	private int size;
	
	//[]  [1]
	//增加结点,即是在结尾增加
 	public void add(E element) {//shift+alt+R可以同时修改所有相同的变量名
		Node node=new Node(element);//先创建一个新的结点
		
		if(first==null) {//当链表里面为空的时候
			
			first=node;
			last=node;
		}
		else {
			node.pre=last;
			node.next=null;
			last.next=node;
			last=node;
		
		}
		size++;
	}
	
 	
 	//重写toString方法
 	public String toString() {
		//["q","a","c"]
 		//挨个遍历链表中的元素。
		Node temp=first;
		StringBuilder s=new StringBuilder();
		s.append("[");
		while(temp!=null) {
			s.append(temp.element+",");
			temp=temp.next;
		}
		s.setCharAt(s.length()-1, ']');
		return s.toString();
	}
 	
 	//["q","a","c"]//2
 	//获得索引位置的元素
 	public E get(int index) {
 		//从第一个开始
 		//判断索引的范围
 		checkRange(index);
 		Node temp=getNode(index);
 		
 		return temp!=null?(E)temp.element:null;//返回结点元素。
 		
 		
 	}

 	
 	//根据索引值获得结点,
 	private Node getNode(int index) {
 		checkRange(index);
 		Node temp=null;
 		if(index<=(size>>1)) {
 			temp=first;
 			for(int i=0;i<index;i++) {
 	 			temp=temp.next;
 			}
 		}
 		else {
 			temp=last;
 			for(int i=size-1;i>index;i--) {
 	 			temp=temp.pre;
 			}
 		}
 		return temp;
 	}
 	
 	
 	
 	//remove 方法
 	public void remove(int index) {
 		checkRange(index);
 		Node temp=getNode(index);
 		if(temp!=null) {
 			Node up=temp.pre;
 			Node down=temp.next;
 			if(up!=null)
 				up.next=down;
 			if(down!=null)
 				down.pre=up;
 			if(index==0)//删除的是第一个元素
 				first=down;
 			if(index==size-1)//删除的是最后一个元素
 				last=up;
 			size--;
 		}
 	}
 	
 	
 	
 	
 	//判断索引是否合法
 	//不需要外部知道的方法可以用private修饰
 	
 	private void checkRange(int index) {
 		if(index<0||index>size-1) {
 			throw new RuntimeException("索引的范围不合法:"+index);
 		}
 	}
 	
 	//在索引位置前插入一个结点,
 	public void add(int index,E element) {
 		checkRange(index);
 		Node newNode=new Node(element);
 		Node temp=getNode(index);
 		if(index==0) {
 			newNode.next=temp;
 			newNode.pre=null;
 			temp.pre=newNode;
 			first=newNode;
 		}
 		
 		if(temp!=null) {
 			Node up=temp.pre;
 			
 			up.next=newNode;
 			newNode.pre=up;
 			
 			newNode.next=temp;
 			temp.pre=newNode;
 		}
 		size++;
 		
 		
 	}
 	
 	
 	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		myLinkedList<Integer> l=new myLinkedList<>();
		l.add(1);
		l.add(2);
		l.add(4);
		l.add(3);
		
//		System.out.println(l);
//		System.out.println(l.get(3));
//		System.out.println(l.get(0));
//		l.remove(0);
//		System.out.println(l);
//		l.remove(3);
		System.out.println(l);
		l.add(0,5);
		System.out.println(l);
		}

}

节点类

public class Node {
	Node pre;//上一个结点
	Node next;//下一个结点
	Object element;//元素数组
	public Node(Node pre, Node next, Object element) {
		super();
		this.pre = pre;
		this.next = next;
		this.element = element;
	}
	
	
	public Node(Object element) {
		super();
		this.element = element;
	}


HashMap

public class myHashMap<K,V> {
	Node2[] table;//位桶数组,用于存放Node2
	int size;

	public myHashMap() {
		super();
		table=new Node2[16];//数组的大小一般为2的整数幂
	}
	
	
	
	public void put(K key,V value) {
		//可以增加数组扩容的方法
		
		
		//定义心得结点对象
		Node2 newNode=new Node2();
		newNode.hash=myHash(key.hashCode(), table.length);//获得新节点的hash值
		newNode.key=key;
		newNode.value =value;
		newNode.next =null;
		
		//根据hash值存放
		
		Node2 temp=table[newNode.hash];//放入hash相应的table中
		boolean keyReplace=false;
		Node2 iterLast=null;//正在遍历的最后一个元素
		if(temp==null) {//如果此处的数组元素为空,则直接将新节点放进去
			table[newNode.hash]=newNode;
			size++;
		}else {//否则遍历数组,如果键重复,则替换,没有重复的就直接放在链表的后面。
			while(temp!=null) {
				//判断key存在,替换
				if(temp.key.equals(key)) {
					keyReplace=true;
					temp.value =value;//只是覆盖value就可以,其他的值不变
					break;
				}else {
					//key不存在,将temp.next=newNode;
					iterLast=temp;
					temp=temp.next;
				}
				
			}
			
			if(!keyReplace) {//如果没有发生键重复
				iterLast.next=newNode;
				size++;
			}
		}

	}
	public int myHash(int v,int length) {
		return v&(length-1);//获得hash值,与操作就是对length取模。
	}
	//重写toString方法
	@Override
	public String toString() {
		//[1:a,2:b]
		StringBuilder sb=new StringBuilder("[");
		for(int i=0;i<table.length;i++) {
			Node2 temp=table[i];//获得第一个元素
			while(temp!=null) {
				sb.append(temp.key+":"+temp.value +",");
				temp=temp.next;
			}
		}
		sb.setCharAt(sb.length()-1, ']');
		return sb.toString();
	}
	
	//增加get方法
	public V get(K key) {
		int hash=myHash(key.hashCode(),table.length);
		V value=null;
		if(table[hash]!=null) {
			Node2 temp=table[hash];
			while(temp!=null) {
				if(temp.key.equals(key)) {
					//如果相等,则说明找到了键值对,返回相应的value
					value=(V) temp.value;
					break;
				}else {
					temp=temp.next ;
					
				}
				
			}
		}
		return value;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		myHashMap<Integer,String> m=new myHashMap<>();
		m.put(1, "a");
		m.put(2,"b");
		m.put(3,"c");
		m.put(3,"d");
		System.out.println(m);
		System.out.println(m.get(1));
		
		
	}

}

/**
 * 用于HashMap的节点类
 * 
 * 
 * @author lenovo
 *
 */
public class Node2<K,V> {
	int hash;
	K key;
	V value;
	Node2 next;
	
}

HashSet

import java.util.Set;
import java.util.TreeSet;

public class myTreeSet {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Set<Integer> set=new TreeSet<>();
		set.add(30);
		set.add(40);
		set.add(20);
		for(Integer m:set) {
			System.out.println(m);
		}
		
		Set<Employee2> set2=new TreeSet<>();
		set2.add(new Employee2(200,"ki",20000));
		set2.add(new Employee2(300,"yi",30000));
		set2.add(new Employee2(400,"ei",40000));
		
		for(Employee2 m:set2) {
			System.out.println(m);
		}
		
	}

}


//实现Comparable接口,需要重写compareTo的方法。
class Employee2 implements Comparable<Employee2>{
	int id;
	String name;
	double salary;
	public Employee2(int id, String name, double salary) {
		super();
		this.id = id;
		this.name = name;
		this.salary = salary;
	}
	
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return " id "+id+" name "+name+" salary "+salary;
	}
	public int compareTo(Employee2 o) {
		//返回负数:小于,返回0:等于,返回整数:大于
		if(this.salary>o.salary) {
			return 1;
		}else if(this.salary<o.salary){
			return -1;
		}else {
			if(this.id>o.id) {
				return 1;
			}else if(this.id<o.id) {
				return -1;
			}else {
				return 0;
			}
		}
	}
}

发布了43 篇原创文章 · 获赞 11 · 访问量 2578

猜你喜欢

转载自blog.csdn.net/weixin_43328816/article/details/104317259