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;
}
}
}
}