Java容器【集合】笔记

【容器】学习笔记

数组就是一个容器,可以在其中放置对象或基本数据类型

数组的优势:

是一种简单的线性序列,可以快速的访问数组元素,效率高,如果从效率和类型检查的角度讲,数组是最好的。

数组的劣势:

不灵活,容量需要实现定义好,不能随着需求的变化而扩容,比如:我们在一个用户管理系统中要把今天注册的所有用户取出来,那么这样的用户有多少个在写程序的时候是无法确定的。因此,在这里就不能使用数组。

泛型

        List list = new ArrayList();
        Map map = new HashMap();

概念

帮助我们建立类型安全的集合,泛型的本质是“数据类型的参数化”,我们可以把“泛型”理解为数据类型的一个占位符(形式参数),即告诉编译器,在调用反形式时必须传入实际类型。

自定义泛型

一般用<T,E,V>三个字母

public class Test {
    public static void main(String[] args) { 
        MyCollection<String> myCollection =new MyCollection<String>();
        myCollection.setObjects("李文泽",0);
        String b =myCollection.get(0);
    }
}
class MyCollection<E>{
    Object[]objects=new Object[5];
    public void setObjects(String e, int index){
        objects[index]=e;
    }
    public E get(int index){
        return (E)objects[index];
    }
}

Collection接口

Collection <String> c = new ArrayList<>();
        c.add("李文泽");
        c.add("泽泽");
        System.out.println(c);
        System.out.println(c.size());
        System.out.println(c.isEmpty());
        System.out.println(c.contains("李文泽"));
        Object[]objects= c.toArray();
        System.out.println(objects);
        c.remove("泽泽");
        System.out.println(c);
        c.clear();
        System.out.println(c.size());

List 类

List 是有序的、可重复的容器、

有序:list中每个元素都有索引标记,可以根据元素的索引标记(在list中的位置)访问元素,从而精确控制这些元素

可重复:list允许加入重复的元素,更确切的讲,;list通常允许满足e1.equals(e2)的元素重复加入容器

list接口常用的实现类有三个:ArrayList、LinkedList、Vector。

List<String> list = new ArrayList<>();
            list.add("A");
            list.add("B");
            list.add("C");
            list.add("D");
            System.out.println(list);
            list.add(2, "李文泽");
            System.out.println(list);
            list.remove(2);
            System.out.println(list);
            list.set(2,"泽泽");
            System.out.println(list);
            System.out.println(list.get(2));
            list.add("C");
            list.add("B");
            list.add("A");
            System.out.println(list);
            System.out.println(list.indexOf("B"));
            System.out.println(list.lastIndexOf("B"));

ArrayList

ArrayList 底层是用数组实现的存储

特点:查询效率高,增删效率低,线程不安全,我们一般使用它

手工实现ArrayList1
增加泛型
public class Arraylist02 <E>{
    private Object[] elementData;
    private int size;
    private static final int DEFALT_CAPACITY=10;
    public Arraylist02(){
        elementData = new Object[DEFALT_CAPACITY];
    }
    public Arraylist02(int capacity){
        elementData = new Object[capacity];
    }
    public void add(E element){
        elementData[size++]=element;
    }
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i=0;i<size;i++){
            sb.append(elementData[i]+",");
        }
        sb.setCharAt(sb.length()-1,']');
        return sb.toString();
    }
    public static void main(String[] args) {
        Test t1 =new Test(20);
        t1.add("aa");
        t1.add("bb");
        System.out.println(t1);
    }
}
不含泛型
private Object[] elementData;
     private int size;
     private static final int DEFALT_CAPACITY=10;
     public Test(){
        elementData = new Object[DEFALT_CAPACITY];
     }
     public Test(int capacity){
         elementData = new Object[capacity];
     }
    public void add(Object obj){
         elementData[size++]=obj;
    }
    @Override
    public String toString() {
       StringBuilder sb = new StringBuilder();
       sb.append("[");
       for (int i=0;i<size;i++){
           sb.append(elementData[i]+",");
       }
       sb.setCharAt(sb.length()-1,']');
       return sb.toString();
    }
    public static void main(String[] args) {
        Test t1 =new Test(20);
        t1.add("aa");
        t1.add("bb");
        System.out.println(t1);
    }
        }
手工实现ArrayList2
数组扩容
public class Arraylist03<E> {
    private Object[] elementData;
    private int size;
    private static final int DEFALT_CAPACITY=10;
    public Arraylist03(){
        elementData = new Object[DEFALT_CAPACITY];
    }
    public Arraylist03(int capacity){
        elementData = new Object[capacity];
    }
    public void add(E element){
        //什么时候扩容
        if (size==elementData.length) {
            //扩容操作
            Object[] newArray = new Object[elementData.length+(elementData.length >> 1)];
            System.arraycopy(elementData, 0, newArray, 0, elementData.length);
            elementData=newArray;
        }
        elementData[size++]=element;

    }
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i=0;i<size;i++){
            sb.append(elementData[i]+",");
        }
        sb.setCharAt(sb.length()-1,']');
        return sb.toString();
    }
    public static void main(String[] args) {
        Arraylist03 s1 = new Arraylist03(20);
        s1.add("aa");
        s1.add("bb");
        for (int  i =0;i<30;i++){
            s1.add("li"+i);
        }
        System.out.println(s1);
    }
}

手工实现ArrayList3(解决索引越界问题)
public class Arraylist04<E> {
    private Object[] elementData;
    private int size;
    private static final int DEFALT_CAPACITY=10;
    public Arraylist04(){
        elementData = new Object[DEFALT_CAPACITY];
    }
    public Arraylist04(int capacity){
        elementData = new Object[capacity];
        if (capacity<0){
            throw new RuntimeException("容器容量不能为负数");
        }else if (capacity==0){
            elementData=new Object[DEFALT_CAPACITY];
        }else {
            elementData=new Object[capacity];
        }
    }
    public void add(E element){
        //什么时候扩容
        if (size==elementData.length) {
            //扩容操作
            Object[] newArray = new Object[elementData.length+(elementData.length >> 1)];
            System.arraycopy(elementData, 0, newArray, 0, elementData.length);
            elementData=newArray;
        }
        elementData[size++]=element;

    }
    public E get(int index){
        return (E) elementData[index];
    }
    public void set(E element,int index){
        //索引合法判断[0,size)
        checkRange(index);
        elementData[index]=element;
    }
    public void checkRange(int index){
        checkRange(index);
        if (index<0||index>size-1){
            //不合法
            throw new RuntimeException("索引不合法:"+index);
        }
    }
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i=0;i<size;i++){
            sb.append(elementData[i]+",");
        }
        sb.setCharAt(sb.length()-1,']');
        return sb.toString();
    }
    public static void main(String[] args) {
        Arraylist04 s1 = new Arraylist04(20);
        s1.add("aa");
        s1.add("bb");
        for (int  i =0;i<30;i++){
            s1.add("li"+i);
        }
        System.out.println(s1);
        s1.set("dd",2);
        System.out.println(s1);
        System.out.println(s1.get(10));
    }
}

手工实现ArrayList4
public class Arraylist05<E> {
    private Object[] elementData;
    private int size;
    private static final int DEFALT_CAPACITY=10;
    public Arraylist05(){
        elementData = new Object[DEFALT_CAPACITY];
    }
    public Arraylist05(int capacity){
        elementData = new Object[capacity];
        if (capacity<0){
            throw new RuntimeException("容器容量不能为负数");
        }else if (capacity==0){
            elementData=new Object[DEFALT_CAPACITY];
        }else {
            elementData=new Object[capacity];
        }
    }
    public int size(){
        return size;
    }
    public boolean isEmpty(){
        return size==0?true:false;
    }
    public void add(E element){
        //什么时候扩容
        if (size==elementData.length) {
            //扩容操作
            Object[] newArray = new Object[elementData.length+(elementData.length >> 1)];
            System.arraycopy(elementData, 0, newArray, 0, elementData.length);
            elementData=newArray;
        }
        elementData[size++]=element;
    }
    public E get(int index){
        return (E) elementData[index];
    }
    public void set(E element,int index){
        //索引合法判断[0,size)
        checkRange(index);
        elementData[index]=element;
    }
    public void remove(E element){
        //element,将它和所有元素挨个比较,获得第一个比较为true的值返回
        for (int i=0;i<size;i++){
            if (element.equals(get(i))){//容器中所有的比较操作都是用equals而不是==
                //将该元素从此处移除
                remove(i);
            }
        }
    }
    public void remove(int index){
        //a.b.c.d.e.f.g.h
        //a.b.c.e.f.g.h 核心是拷贝
        int numMoved=elementData.length-index-1;
        System.arraycopy(elementData,index+1,elementData,index,numMoved);
        if (numMoved>0) {
            System.arraycopy(elementData, index + 1, elementData, index, numMoved);
        }
            elementData[--size]=null;
        }
    public void checkRange(int index){
        checkRange(index);
        if (index<0||index>size-1){
            //不合法
            throw new RuntimeException("索引不合法:"+index);
        }
    }
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i=0;i<size;i++){
            sb.append(elementData[i]+",");
        }
        sb.setCharAt(sb.length()-1,']');
        return sb.toString();
    }
    public static void main(String[] args) {
        Arraylist05 s1 = new Arraylist05();
        s1.add("aa");
        s1.add("bb");
        for (int  i =0;i<30;i++){
            s1.add("li"+i);
        }
        s1.remove(0);
        s1.remove(1);
        s1.remove(2);
        s1.add("李文泽");
        System.out.println(s1);
        System.out.println(s1.size);
        System.out.println(s1.isEmpty());
    }
}

LinkedList类

底层结构是链表

节点类
public class Node {
    Node previous;//上一个节点
    Node next;//数据
    Object element;//下一个节点

    public Node(Node previous, Node next, Object element) {
        this.previous = previous;
        this.next = next;
        this.element = element;
    }

    public Node(Object element) {
        this.element = element;
    }
}

手工实现LinkedList1 ——add方法
public class SxtLinkedList01{
    private Node first;
    private Node last;

    private int size;
    public void add(Object obj){
        Node node = new Node(obj);
        if (first==null){
            /* node.previous=null;
             node.next=null;*/
            first=node;
            last=node;
        }else {
            node.previous=last;
            node.next=null;

            last.next=node;
            last=node;
        }
    }
    @Override
    public String toString() {
       //[a,b,c] first =a,last=c
        StringBuilder sb =new StringBuilder("[");
        Node temp = first;
        while (temp!=null){
            sb.append(temp.element+",");
            temp=temp.next;
        }
        sb.setCharAt(sb.length()-1,']');
        return sb.toString();
    }

    public static void main(String[] args) {
        SxtLinkedList01 list01=new SxtLinkedList01();
        list01.add("a");
        list01.add("b");
        list01.add("c");
        System.out.println(list01);
    }

}

手工实现LinkedList2 ——get方法
public class SxtLinkedList02 {
        private Node first;
        private Node last;
        private int size;
        public Object get(int index){
            System.out.println(size);
            if (index<0||index>size-1){
                throw new RuntimeException("索引数字不合法:"+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.previous;
                }
            }
            return temp.element;
        }
        public void add(Object obj){
            Node node = new Node(obj);
            if (first==null){
            /* node.previous=null;
             node.next=null;*/
                first=node;
                last=node;
            }else {
                node.previous=last;
                node.next=null;
                last.next=node;
                last=node;
            }
            size++;
        }
        @Override
        public String toString() {
            //[a,b,c] first =a,last=c
            StringBuilder sb =new StringBuilder("[");
            Node temp = first;
            while (temp!=null){
                sb.append(temp.element+",");
                temp=temp.next;
            }
            sb.setCharAt(sb.length()-1,']');
            return sb.toString();
        }
        public static void main(String[] args) {
            cn.sxt.gao.SxtLinkedList02 list02=new cn.sxt.gao.SxtLinkedList02();
            list02.add("a");
            list02.add("b");
            list02.add("c");
            list02.add("d");
            list02.add("e");
            list02.add("f");
            System.out.println(list02.get(3));
        }
    }

手工实现LinkedList3 ——remove方法
public class SxtLinkedList03 {
        private Node first;
        private Node last;
        private int size;
        public void remove(int index){
            Node temp = getNode(index);
            if (temp!=null){
                Node up = temp.previous;
                Node down = temp.next;
                if (up!=null){
                    up.next=down;
                }
                if (down!=null){
                    down.previous=up;
                }
                //被删除的元素是第一个元素时
                if (index==0){
                    first=down;
                }
                //被删除的元素是第二个元素时
                if (index==size-1){
                    last=up;
                }
                size--;
            }
        }
        public Object get(int index){
            System.out.println(size);
            if (index<0||index>size-1){
                throw new RuntimeException("索引数字不合法:"+index);
            }
            Node temp=getNode(index);
            return temp!=null?temp.element:null;
        }
        public Node getNode(int 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.previous;
                }
            }
            return temp;
        }
        public void add(Object obj){
            Node node = new Node(obj);
            if (first==null){
            /* node.previous=null;
             node.next=null;*/
                first=node;
                last=node;
            }else {
                node.previous=last;
                node.next=null;
                last.next=node;
                last=node;
            }
            size++;
        }
        @Override
        public String toString() {
            //[a,b,c] first =a,last=c
            StringBuilder sb =new StringBuilder("[");
            Node temp = first;
            while (temp!=null){
                sb.append(temp.element+",");
                temp=temp.next;
            }
            sb.setCharAt(sb.length()-1,']');
            return sb.toString();
        }
        public static void main(String[] args) {
            cn.sxt.gao.SxtLinkedList03 list03=new cn.sxt.gao.SxtLinkedList03();
            list03.add("a");
            list03.add("b");
            list03.add("c");
            list03.add("d");
            list03.add("e");
            list03.add("f");
            System.out.println(list03);
            list03.remove(3);
            System.out.println(list03);
            list03.remove(0);
            System.out.println(list03);
            list03.remove(3);
            System.out.println(list03);
        }
    }

Vector向量

vector底层是用数组实现的list,相关的方法都加了同步减产,因此“线程安全,效率低”

如何选用ArrayList、linkedlist、vector

  1. 需要线程安全时2,用vector
  2. 不存在线程安全问题时,并且查找较多用ArrayList(一般使用它)
  3. 不存在线程安全问题时,增加或删除元素较多用linkedlist

Map接口

Map就是用来存储键值对的,Map类存储的“键值对”通过键来表示,所以“键对象”不能重复。

import java.util.HashMap;
import java.util.Map;

public class TestMap {
    public static void main(String[] args) {
        Map<Integer,String> m1 = new HashMap<>();
        m1.put(1,"one");
        m1.put(2,"two");
        m1.put(3,"three");

        System.out.println(m1.get(1));
        System.out.println(m1.isEmpty());
        System.out.println(m1.containsKey(2));
        System.out.println(m1.containsValue("four"));

        Map<Integer,String> m2 = new HashMap<>();
        m2.put(4,"四");
        m2.put(5,"五");
        m1.putAll(m2);

        System.out.println(m1);
        //map中键不能重复,如果重复则新的覆盖旧的(是否重复是根据equals方法来判断)
        m1.put(3,"三");
        System.out.println(m1);

    }
}

import java.util.HashMap;
import java.util.Map;

public class TestMap2 {
    public static void main(String[] args) {
        Employee e1 =new Employee(1001,"李文泽",50000);
        Employee e2 =new Employee(1002,"李文泽1",5000);
        Employee e3 =new Employee(1003,"李文泽2",6000);
        Employee e4 =new Employee(1003,"李文泽3",6000);
        Map<Integer, Employee> map =new HashMap<>();
        map.put(1001,e1);
        map.put(1002,e2);
        map.put(1003,e3);
        map.put(1004,e4);

        Employee emp = map.get(1001);
        System.out.println(emp.getEname());

        System.out.println(map);
    }
}
class Employee{
    private int id;
    private String ename;
    private double salary;

    public Employee(int id, String ename, double salary) {
        this.id = id;
        this.ename = ename;
        this.salary = salary;
    }
    @Override
    public String toString(){
        return "id:"+id+" name:"+ename+" 薪水"+salary;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }
}

HashMap底层原理

HashMap底层实现采用了哈希表,这是一种非常重要的数据结构

哈希表的基本结构是“数组+链表’’.

public class test {
    public static void main(String[] args) {
        int h = 25860399;
        int length = 16;
        myHash(h,length);

    }
    public static int myHash(int h, int length){
        System.out.println(h&(length-1));
        System.out.println(h%length);
        return h&(length-1);
    }
}

Java中规定,两个内容相同的(equals()为true)的对象必须具有相同的hashcode,因为如果equals()为true而两个对象的hashcode不同;那在整个存储过程中就发生了悖论

扩容问题

HashMap的位桶数组,初始大小为16.实际使用时,显然大小是可变的。如果位桶数组中的元素达到(0.75*数组 length),就重新调整数组大小变为原来的2倍大小

扩容很耗时,扩容的本质是定义新的更大的数组,并将旧数组内容挨个拷贝到新数组中。

手工实现HashMap1_基本结构_–put存储键值对
//用于HashMap
public class Node {
    int hash;
    Object key;
    Object value;
    Node next;
}
public class SxtHashMap01 {
    Node[] table;//位桶数组
    int size;//存放键值对的个数
    public SxtHashMap01(){
        table=new Node[16];//长度一般定义为2的整数幂
    }
    public void put(Object key,Object value){
        Node newNode = new Node();
        newNode.hash=myHash(key.hashCode(),table.length);
        newNode.key=key;
        newNode.value=value;
        newNode.next= null;

        Node temp = table[newNode.hash];
        if (temp==null){
            //此处数组元素为Jong,则直接将新节点放进去
            table[newNode.hash]=newNode;
        }else {
            //此处数组元素不为空,则遍历对应链表。

        }
    }
    public static void main(String[] args) {
        SxtHashMap01 m = new SxtHashMap01();
        m.put(10,"aa");
        m.put(20,"bb");
        m.put(30,"cc");
        System.out.println(m);
    }
    public int myHash(int v,int length){
        System.out.println("hash in myHash:"+(v&(length-1)));//直接位运算,效率高
        System.out.println("hash in myHash:"+(v%(length-1)));//取模运算,效率低
        return v&(length-1);
    }

}

手工实现HashMap2
/**
 * 自定义一个HashMap
 * 实现了put方法增加键值对,并解决了键重复的时候覆盖相应的节点
 */
public class SxtHashMap01 {
    Node[] table;//位桶数组
    int size;//存放键值对的个数
    public SxtHashMap01(){
        table=new Node[16];//长度一般定义为2的整数幂
    }
    public void put(Object key,Object value) {
        Node newNode = new Node();
        newNode.hash = myHash(key.hashCode(), table.length);
        newNode.key = key;
        newNode.value = value;
        newNode.next = null;

        Node temp = table[newNode.hash];
        Node iterLast = null;
        boolean keyRepeat = false;
        if (temp == null) {
            //此处数组元素为Jong,则直接将新节点放进去
            table[newNode.hash] = newNode;
        } else {
            //此处数组元素不为空,则遍历对应链表。
            while (temp != null) {
                //判断key如果重复,则覆盖
                if (temp.key.equals(key)) {
                    keyRepeat = true;
                    System.out.println("key重复了");
                    temp.value = value;//只是覆盖value即可,其他的值(hash。key。next)保持不变
                    break;
                } else {
                    //key不重复,则遍历下一个。
                    iterLast = temp;
                    temp = temp.next;
                }
            }
            if (!keyRepeat) {
                iterLast.next = newNode;
            }
        }

    }
    public static void main(String[] args) {
        SxtHashMap01 m = new SxtHashMap01();
        m.put(10, "aa");
        m.put(20, "bb");
        m.put(30, "cc");
        m.put(20, "ssss");
        m.put(53,"gg");
        m.put(69,"hh");
        m.put(85,"kk");
        System.out.println(m);
        for (int i = 10; i < 100; i++) {
            System.out.println(i+"---"+myHash(i, 16));
        }
    }
    public static int myHash(int v,int length){
        System.out.println("hash in myHash:"+(v&(length-1)));//直接位运算,效率高
        System.out.println("hash in myHash:"+(v%(length-1)));//取模运算,效率低
        return v&(length-1);
    }

}

手工实现HashMap3
/**
 * 自定义一个HashMap
 * 实现toString方法,方便查看map中的键值对信息
 */
public class SxtHashMap01 {
    Node[] table;//位桶数组
    int size;//存放键值对的个数
    public SxtHashMap01(){
        table=new Node[16];//长度一般定义为2的整数幂
    }

    public Object get(Object key){
        int hash=myHash(key.hashCode(),table.length);
        Object value= null;
        if (table[hash]!=null){
            Node temp= table[hash];

            while (temp!=null){
                if (temp.key.equals(key)){  //如果相等,则说明找到了键值对,返回相应的value
                    value=temp.value;
                    break;
                }else {
                    temp=temp.next;
                }
            }
        }
        return value;

    }


    public void put(Object key,Object value) {
        //如果要完善,还需要考虑数组扩容的问题!!
        Node newNode = new Node();
        newNode.hash = myHash(key.hashCode(), table.length);
        newNode.key = key;
        newNode.value = value;
        newNode.next = null;

        Node temp = table[newNode.hash];
        Node iterLast = null;
        boolean keyRepeat = false;
        if (temp == null) {
            //此处数组元素为Jong,则直接将新节点放进去
            table[newNode.hash] = newNode;
            size++;
        } else {
            //此处数组元素不为空,则遍历对应链表。
            while (temp != null) {
                //判断key如果重复,则覆盖
                if (temp.key.equals(key)) {
                    keyRepeat = true;
                    temp.value = value;//只是覆盖value即可,其他的值(hash。key。next)保持不变
                    break;
                } else {
                    //key不重复,则遍历下一个。
                    iterLast = temp;
                    temp = temp.next;
                }
            }
            if (!keyRepeat) {
                iterLast.next = newNode;
                size++;
            }
        }

    }
    public static void main(String[] args) {
        SxtHashMap01 m = new SxtHashMap01();
        m.put(10, "aa");
        m.put(20, "bb");
        m.put(30, "cc");
        m.put(20, "ssss");
        m.put(53,"gg");
        m.put(69,"hh");
        m.put(85,"kk");
        System.out.println(m.get(69));
    }
    public static int myHash(int v,int length){
        return v&(length-1);
    }

}

手工实现HashMap4_get查找键值对
public Object get(Object key){
        int hash=myHash(key.hashCode(),table.length);
        Object value= null;
        if (table[hash]!=null){
            Node temp= table[hash];

            while (temp!=null){
                if (temp.key.equals(key)){  //如果相等,则说明找到了键值对,返回相应的value
                    value=temp.value;
                    break;
                }else {
                    temp=temp.next;
                }
            }
        }
        return value;

    }
手工实现HashMap5_完善封装、实现泛型
/**
 * 自定义一个HashMap
 * 完善封装,增加泛型
 */
public class SxtHashMap01<K,V> {
    Node[] table;//位桶数组
    int size;//存放键值对的个数
    public SxtHashMap01(){
        table=new Node[16];//长度一般定义为2的整数幂
    }

    public V get(K key){
        int hash=myHash(key.hashCode(),table.length);
        V value= null;
        if (table[hash]!=null){
            Node temp= table[hash];

            while (temp!=null){
                if (temp.key.equals(key)){  //如果相等,则说明找到了键值对,返回相应的value
                    value=(V)temp.value;
                    break;
                }else {
                    temp=temp.next;
                }
            }
        }
        return value;
    }
    public void put(K key,V value) {
        //如果要完善,还需要考虑数组扩容的问题!!
        Node newNode = new Node();
        newNode.hash = myHash(key.hashCode(), table.length);
        newNode.key = key;
        newNode.value = value;
        newNode.next = null;

        Node temp = table[newNode.hash];
        Node iterLast = null;
        boolean keyRepeat = false;
        if (temp == null) {
            //此处数组元素为Jong,则直接将新节点放进去
            table[newNode.hash] = newNode;
            size++;
        } else {
            //此处数组元素不为空,则遍历对应链表。
            while (temp != null) {
                //判断key如果重复,则覆盖
                if (temp.key.equals(key)) {
                    keyRepeat = true;
                    temp.value = value;//只是覆盖value即可,其他的值(hash。key。next)保持不变
                    break;
                } else {
                    //key不重复,则遍历下一个。
                    iterLast = temp;
                    temp = temp.next;
                }
            }
            if (!keyRepeat) {
                iterLast.next = newNode;
                size++;
            }
        }

    }
    public static void main(String[] args) {
        SxtHashMap01 <Integer,String> m = new SxtHashMap01<>();
        m.put(10, "aa");
        m.put(20, "bb");
        System.out.println(m.get(85));

    }
TreeMap使用和底层原理_Comparable接口__HashTable特点
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;

public class TestTreeMap {
    public static void main(String[] args) {
        Map<Integer,String> treemap1=new TreeMap<>();
        treemap1.put(20,"aa");
        treemap1.put(3,"bb");
        treemap1.put(6,"cc");
        //按照key递增的方式排序
        for (Integer key:treemap1.keySet()){
            System.out.println(key+"---"+treemap1.get(key));
        }
        Map<Emp,String> treemap2= new TreeMap<>();
        treemap2.put(new Emp(100,"张三",50000),"张三是一个好小伙");
        treemap2.put(new Emp(200,"李四",5000),"李四工作不积极");
        treemap2.put(new Emp(150,"王五",6000),"王五工作还不错");
        for (Emp key:treemap2.keySet()){
            System.out.println(key+"---"+treemap2.get(key) );
        }


    }
}
class Emp implements Comparable<Emp>{
    int id;
    String name;
    double salary;
    public Emp(int id,String name,double salary){
        super();
        this.id=id;
        this.name=name;
        this.salary=salary;
    }
    @Override
    public String toString(){
        return "id:"+id+" name:"+name+" salary:"+salary;
    }
    @Override
    public int compareTo(Emp 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;
            }
        }
    }
}
HashMap和HashTable的区别
  1. HashMap:线程不安全,效率高,允许使用key或value为null
  2. HashTable:线程安全,效率低,不允许使用key或value为null
手工实现HashSet
import java.util.HashMap;

public class SxtHashSet {
    HashMap map;

    private static final Object PRESENT = new Object();

    public SxtHashSet(){
        map= new HashMap();
    }
    public int size(){
        return map.size();
    }
    public void add(Object o){
        map.put(o,PRESENT);
    }
    @Override
    public String toString(){
        StringBuilder stringBuilder= new StringBuilder();
        stringBuilder.append("[");

        for (Object key:map.keySet()){
            stringBuilder.append(key+",");
        }
        stringBuilder.setCharAt(stringBuilder.length()-1,']');
        return stringBuilder.toString();
    }


    public static void main(String[] args) {
        SxtHashSet sxtHashSet = new SxtHashSet();
        sxtHashSet.add("aaa");
        sxtHashSet.add("bbb");
        sxtHashSet.add("ccc");

        System.out.println(sxtHashSet);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值