一、泛型

1、在JDK1.4以前,所有的集合元素全都按照Object来存储,拿出来还要进行强制转型。由于这样的做法有太多的缺点,容易出现ClassCaseException,不安全,让人不省心,于是乎JDK5之后出现了泛型。

2、什么是泛型,通俗的讲,就是在Java文件编译期对类型进行检查。比如:List<String> string = new ArrayList<String>(); 它只能装String类型的对象,否则编译时报错。

二、自定义ArrayList

1、ArrayList顾名思义,底层就是使用数组实现的List。

2、代码

package com.collection.arrayList;

import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;

//实现Iterable接口,就可以使用forEach
public class MyArrayList<E> implements Iterable<E> {
//Object的数组,Java没有泛型数组
private Object[] elementData = null;
private int size = 0;

  //默认的数组大小是10
public MyArrayList() {
this(10); }
public MyArrayList(int cacaptiy) {
elementData = new Object[cacaptiy];
} public boolean add(E obj) {
//如果当前元素个数已经跟数组一样大了,就扩容
if(size >= elementData.length) {
this.ensureCapacityInternal(elementData.length); }
elementData[size++] = obj; return true;
} @SuppressWarnings("unchecked")
public <T> T[] toArray(T[] arr) { if(arr.length < size) { return (T[]) Arrays.copyOf(elementData, size, arr.getClass());
}
System.arraycopy(elementData, 0, arr, 0, arr.length);
if(arr.length > size) {
arr[size] = null; } return arr;
} @SuppressWarnings("unchecked")
public E[] toArray() { return (E[]) Arrays.copyOf(elementData, elementData.length);
} public boolean addAll(MyArrayList<E> list) { for(int i = 0; i < list.size; i++) {
this.add(list.get(i));
} return true;
} public boolean set(int index, E obj) {
if(index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
ensureCapacityInternal(1);
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = obj;
size ++;
return true; } public boolean remove(int index) {
if(index < 0 || index >= size) { throw new ArrayIndexOutOfBoundsException(); }
System.arraycopy(elementData, index + 1, elementData, index, size - index -1);
size --;
return true; } public boolean remove(E obj) { for(int i = 0; i < elementData.length; i++) {
if(obj == elementData[i]) {
System.arraycopy(elementData, i + 1, elementData, i, size - i - 1);
size --;
return true;
} else if(obj.equals(elementData[i]) && obj.hashCode() == elementData[i].hashCode()) { System.arraycopy(elementData, i + 1, elementData, i, size - i - 1);
size --;
return true;
} } return false; } @SuppressWarnings("unchecked")
public E get(int index) {
if(index < 0 || index >= size) { throw new ArrayIndexOutOfBoundsException(); }
return (E) elementData[index]; } public void ensureCapacityInternal(int cacaptiy) {
Object[] newArr = new Object[elementData.length + cacaptiy];
System.arraycopy(elementData, 0, newArr, 0, elementData.length);
elementData = newArr;
} public int size() { return size;
} public boolean isEmpty() { return size == 0; } public void clear() { for(int i = 0; i <size; i++) {
elementData[i] = null;
}
size = 0;
} public Iterator<E> iterator() { return new Itr();
} private class Itr implements Iterator<E>{
private int cursor = 0;
private int lastRet = -1; @Override
public boolean hasNext() {
return cursor != size();
} @SuppressWarnings("unchecked")
@Override
public E next() {
if(cursor == size()) {
throw new NoSuchElementException(); }
lastRet = cursor;
return (E) elementData[cursor ++];
} public void remove() {
if(lastRet == -1) {
throw new IllegalStateException();
}
MyArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1; } } }

三、自定义LinkedList

1、LinkedList底层是用链表实现的

2、先定义一个Node类

package com.collection.linkedList;

public class Node {
//前一个节点的引用
private Node prev;
//存储的数据
private Object object;
//下一个节点的引用
private Node next; public Node getPrev() {
return prev;
} public void setPrev(Node prev) {
this.prev = prev;
} public Object getObject() {
return object;
} public void setObject(Object object) {
this.object = object;
} public Node getNext() {
return next;
} public void setNext(Node next) {
this.next = next;
} }

3、MyLinkedList.java

package com.collection.linkedList;

public class MyLinkedList<E> {

    private Node header;//链表的节点头

    private Node tail;//链表的结尾

    private int size;//记录当前元素的大小

    public MyLinkedList() {

    }
/**
* 在某个位置插入元素
* @param index
* @param obj
*/
public void set(int index, E obj) {
if(index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
}
Node node = new Node();
node.setObject(obj);
Node temp1 = header;
Node temp = null;
Node temp2 = tail;
Node prev = null;
//除以,看看这个index离header近还是tail近
if(index >= (size >> 1)) { for(int i = 0; i < index; i++) {
temp1 = temp1.getNext();
}
temp = temp1;
} else {
for(int i = 0; i < size - index - 1; i++) {
temp2 = temp2.getPrev();
}
temp = temp2;
}
prev = temp.getPrev();
if(prev != null) { prev.setNext(node); } else {
header = node;
}
node.setNext(temp);
temp.setPrev(node);
size ++;
} public boolean remove(int index) {
if(index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
} Node temp = header; for(int i = 0; i < index; i++) {
temp = temp.getNext(); }
Node prev = temp.getPrev();
Node next = temp.getNext();
if(prev != null) { prev.setNext(next);
} else { header = next;
}
if(next != null) { next.setPrev(prev);
} else { tail = prev;
}
size --;
return true; } public boolean remove(Object obj) {
if(obj == null) { return false;
}
Node temp = header;
Node prev = null;
Node next = null; while(temp != null) {
if(temp.getObject() == obj) { prev = temp.getPrev();
next = temp.getNext();
if(prev != null) { prev.setNext(next);
} else {
header = next; }
if(next != null) { next.setPrev(prev);
} else {
tail = prev;
}
size --;
return true; } else if(temp.getObject().equals(obj) && obj.hashCode() == temp.getObject().hashCode()) { prev = temp.getPrev();
next = temp.getNext();
if(prev != null) { prev.setNext(next);
} else { header = next;
}
if(next != null) { next.setPrev(prev);
} else {
tail = prev;
}
size --;
return true;
}
temp = temp.getNext();
} return false; } public boolean add(E obj) {
Node node = new Node();
node.setObject(obj);
if(header == null) {
header = node;
header.setPrev(null);
tail = node;
node.setNext(null); } else {
node.setPrev(tail);
tail.setNext(node);
tail = node;
node.setNext(null); }
size ++;
return true;
} @SuppressWarnings("unchecked")
public E get(int index) {
if(index < 0 || index >= size) {
throw new IndexOutOfBoundsException();
} Node temp = header; for(int i = 0; i < index; i++) {
temp = temp.getNext(); } return (E) temp.getObject();
} public int size() { return size;
} }

四、自定义HashMap

1、HashMap的底层是用数组和链表实现的,数组的元素是链表,链表里存的是键值对对象

2、键值对类MyEntry.java

package com.collection.hashMap;

public class MyEntry {

    private Object key;//键

    private Object value;//值

    public MyEntry(Object key, Object value) {
this.key = key;
this.value = value; } public Object getKey() {
return key;
} public void setKey(Object key) {
this.key = key;
} public Object getValue() {
return value;
} public void setValue(Object value) {
this.value = value;
} }

3、MyHashMap.java

package com.collection.hashMap;

import java.util.LinkedList;

/**
* hashmap是由数组和链表一起构成的
* 由于使用的是hashCode,顺序不能保证,它是无顺序的。
* @author may
*
* @param <E>
* @param <U>
*/
public class MyHashMap<E, U> { private Object[] elementData = null; private int size; private int cacaptiy = 10; public MyHashMap() { elementData = new Object[cacaptiy];
} @SuppressWarnings("unchecked")
public boolean put(E key, U value) {
int hashCode = Math.abs(key.hashCode());
MyEntry entry = new MyEntry(key, value);
LinkedList<MyEntry> linkedList = (LinkedList<MyEntry>) elementData[hashCode % cacaptiy];
//key的hashCode可能会重复,需要做判断
if(linkedList != null) {
boolean flag = false;
for(int i = 0; i < linkedList.size(); i++) {
if(linkedList.get(i).getKey().equals(key)) { linkedList.get(i).setValue(value);
flag = true;//return;
break;
}
}
if(!flag) { linkedList.add(entry);
size ++;
} } else {
linkedList = new LinkedList<MyEntry>();
linkedList.add(entry);
if(size == cacaptiy) {
esureCacaptiy(cacaptiy);
}
elementData[hashCode % cacaptiy] = linkedList;
size ++;
} return true;
} public void esureCacaptiy(int increment) {
Object[] obj = new Object[cacaptiy + increment];
cacaptiy = cacaptiy + increment;
System.arraycopy(elementData, 0, obj, 0, elementData.length);
elementData = obj;
} @SuppressWarnings("unchecked")
public U get(E key) {
int hashCode = key.hashCode();
LinkedList<MyEntry> linkedList = (LinkedList<MyEntry>) elementData[hashCode % cacaptiy];
if(linkedList != null) { for(int i = 0; i < linkedList.size(); i++) {
if(linkedList.get(i).getKey().equals(key)) { return (U) linkedList.get(i).getValue(); } } } return null; } public int size() { return size;
} }

五、自定义HashSet

1、HashSet的底层用的是HashMap,它保存的值就是HashMap里的key

2、代码

package com.collection.hashSet;

import java.util.HashMap;

/**
* HashSet底层是用HashMap实现的,是无序的
* @author may
*
* @param <K>
*/
public class MyHashSet<K> { private HashMap<K, Object> map = null; //map的值是固定的
private final static Object PRESENT = new Object(); public boolean add(K obj) {
map.put(obj, PRESENT);
return true; } public boolean remove(K obj) {
map.remove(obj); return true;
} }

自定义Java集合的更多相关文章

  1. Java集合框架实现自定义排序

    Java集合框架针对不同的数据结构提供了多种排序的方法,虽然很多时候我们可以自己实现排序,比如数组等,但是灵活的使用JDK提供的排序方法,可以提高开发效率,而且通常JDK的实现要比自己造的轮子性能更优 ...

  2. JAVA集合四:比较器--类自定义排序

    参考链接: HOW2J.CN 前言 对于JAVA集合,都能够用集合的工具类Collections 提供的方法: Collections.sort(List list) Collections.sort ...

  3. Redis序列化存储Java集合List等自定义类型

    在"Redis学习总结和相关资料"http://blog.csdn.net/fansunion/article/details/49278209 这篇文章中,对Redis做了总体的 ...

  4. Java集合框架List,Map,Set等全面介绍

    Java集合框架的基本接口/类层次结构: java.util.Collection [I]+--java.util.List [I]   +--java.util.ArrayList [C]   +- ...

  5. 【集合框架】Java集合框架综述

    一.前言 现笔者打算做关于Java集合框架的教程,具体是打算分析Java源码,因为平时在写程序的过程中用Java集合特别频繁,但是对于里面一些具体的原理还没有进行很好的梳理,所以拟从源码的角度去熟悉梳 ...

  6. (转)Java集合框架:HashMap

    来源:朱小厮 链接:http://blog.csdn.net/u013256816/article/details/50912762 Java集合框架概述 Java集合框架无论是在工作.学习.面试中都 ...

  7. Java集合面试题

    1.Java集合框架是什么?说出一些集合框架的优点? 每种编程语言中都有集合,最初的Java版本包含几种集合类:Vector.Stack.HashTable和Array.随着集合的广泛使用,Java1 ...

  8. 【JAVA集合框架之工具类】

    一.概述 JAVA集合框架中有两个很重要的工具类,一个是Collections,另一个是Arrays.分别封装了对集合的操作方法和对数组的操作方法,这些操作方法使得程序员的开发更加高效. public ...

  9. 【JAVA集合框架之Map】

    一.概述.1.Map是一种接口,在JAVA集合框架中是以一种非常重要的集合.2.Map一次添加一对元素,所以又称为“双列集合”(Collection一次添加一个元素,所以又称为“单列集合”)3.Map ...

随机推荐

  1. spring mvc 4 校验

    一.controller中添加: @ResourceGatewayValidator gatewayValidator; @RequestMapping(value = "/gateway/ ...

  2. git 命令记录

    git log 配置 git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -% ...

  3. Mybatis获取插入记录的自增长ID(转)

    1.在Mybatis Mapper文件中添加属性“useGeneratedKeys”和“keyProperty”,其中keyProperty是Java对象的属性名,而不是表格的字段名. <ins ...

  4. [杂] BOSE QC15维修小记

    有一句话大概是这样说的“其他的耳机是靠嘴说的,BOSE是靠耳朵听的”,2010年就开始馋QC3,直到2012年在Vancouver的BOSE店里,在震耳欲聋的模拟噪音中带上QC15那一刻,下了决心. ...

  5. iOS 8潜在的取证问题

    Apple于今天正式发布了iOS 8推送升级 大概琢磨了一下: 1. 可以确定,iOS 7中存在的File relay等所谓后门服务已经被修正,目前Oxygen和我们采用这种服务提取的功能将不再适用于 ...

  6. vmware 修改IP 提示子网掩码错误~

    我打开[编辑]->[虚拟网络编辑器]菜单 修改网络设置 提示 子网掩码错误 如下图所示 上网查询,使用如下方法解决问题 这个虚拟网络编辑器是给你添加网卡的,你添加vmnet1就是在你真实的电脑上 ...

  7. 冒泡排序,sql分页语句

    对数组中的数字进行排序 public int[] PopSmall(int[] IntArray) { ; ; i < IntArray.Length - ; i++) { ; j < I ...

  8. Row_Number()显示行号

    SELECT *, Row_Number() OVER (partition by deptid ORDER BY salary desc) rank FROM employee Row_Number ...

  9. db2数据库安装注意几个问题

    1.安装数据库的时候,db2用户使用的是系统中的用户.创建完数据库你会发现你电脑多了一个用户(可以在控制面板中查看到) 2.安装完数据库需要创建数据库.打开命令行cmd(注意一定要用管理员身份打开,不 ...

  10. jquery 农历日历 可自适应

    在网上找了许多大牛做的农历日历,但是不是不符合项目中的要求,就是本身就有问题有Bug ,把大牛门的做日历看了n遍 自己又改造了一遍得到了这个:随后日历又要做个自适应的长宽,又在js中改造代码..... ...