HashMap的介绍,自定义HashMap,Lambda表达式使用

一、HashMap

存储键值对的数据,由key-value组成。如果使用hashMap存储数据,key是自定义的引用的数据类型,一定要重写hashcode()和equals()方法。

  • 哈希表(数组+链表+红黑树):当桶中的数据超过8个,把结构当前链表结构变为红黑树。

  • 初始容量:16

  • 加载因子:0.75 当16*0.75达到临界点12进行扩容

  • 扩容: 扩容位桶的大小

自定义HashMap的创建

package com.shsxt.map02;
/*
 * 自定义简单实现HashMap
 */
public class MyHashMap {
	Node[] table;//位桶数组
	int size;  //存储数据的个数
	
	public MyHashMap() {
		table = new Node[16]; //默认初始容量为16  length为2的整数幂
	}
	
	//添加put
	public void put(Object key,Object value){
		int hash=myHash(key.hashCode(),table.length);
		Node newNode=new Node(); //存储当前键值对的节点
		newNode.hash=hash;
		newNode.key=key;
		newNode.Value=value;
		newNode.next= null;
		
		Node node=table[hash];//hash是刚刚根据key计算出来的桶的位置|数组的索引
		//现在桶中没有节点数据,我当前节点newNode就作为第一个
		if(node==null){
			table[hash]=newNode;
			size++;
		}else{
			//1.拿到链表头节点  如果node不等于null,就作为链表头节点存在
			while(true){
				//如果当前key与桶中的已有节点key相等,value覆盖
				if(node.key.equals(key)){
					node.Value=value;
					break;
				}
				//判断当前是否就为最后一个节点
				if(node.next==null){
					node.next=newNode;
					size++;
					break;
				}
				//如果没有覆盖,继续从我这个节点找到我的下一个节点
				node=node.next; //node用于是当前要比较的桶中的数据节点
			}
		}
	}
	
	/*
	 * 根据key的hashcode()码计算hash值
	 * 返回值:桶的位置
	 * 参数1: key的hashcode()
	 * 参数2: 数组的长度
	 */
	public int myHash(int keycode,int length){
		//System.out.println(keycode % length);
		//System.out.println(keycode & length-1);
		return keycode & length-1;
	}
	
	public static void main(String[] args) {
		MyHashMap my=new MyHashMap();
		System.out.println(my.size);
		my.put(10, "aa");
		my.put(20, "bb");
		my.put(30, "cc");
		System.out.println(my.size);
		my.put(40, "haha");
		System.out.println(my.size);
		my.put(40, "hehe");
		System.out.println(my.size);
	}
}

二、比较器

使用Collections.sort();进行比较

1.内部比较器(自然排序):实现一个Comparable的接口,重写方法compareTo() 在方法内部定义默认比较规则每次修改,都要修改源代码,硬编码 。

package com.collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
​
/**
 * 定义一个ArrayList,存储多个Student类型的数据,使用Collecitons的sort方法进行排序,
 *  排序规则:1)根据身高降序排序
 *         2)根据姓名升序排序
 * 
 * */
public class TextCompare {
    public static void main(String[] args) {
        List<Student> list=new ArrayList();
        Student s=new Student("zsh",175.5,18);
        Student s1=new Student("ls",180,18);
        Student s2=new Student("tydf",165.5,18);
        list.add(s);
        list.add(s1);
        list.add(s2);
        System.out.println(list);
        Collections.sort(list);
        System.out.println(list);
    }
}
class Student implements Comparable<Student>{
    private String name;
    private double height;
    private int age;
    
    public Student() {
        super();
    }
    
    public Student(String name, double height, int age) {
        super();
        this.name = name;
        this.height = height;
        this.age = age;
    }
​
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getHeight() {
        return height;
    }
    public void setHeight(double height) {
        this.height = height;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", height=" + height + ", age=" + age + "]";
    }
​
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        long temp;
        temp = Double.doubleToLongBits(height);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
​
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age != other.age)
            return false;
        if (Double.doubleToLongBits(height) != Double.doubleToLongBits(other.height))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    //内部比较器
    @Override
    public int compareTo(Student o) {
        
        //return (int) (o.height-this.height);//根据身高
        return this.name .compareTo(o.name);//根据姓名
    }
    
}
运行结果:
[Student [name=zsh, height=175.5, age=18], Student [name=ls, height=180.0, age=18], Student [name=tydf, height=165.5, age=18]]
[Student [name=ls, height=180.0, age=18], Student [name=tydf, height=165.5, age=18], Student [name=zsh, height=175.5, age=18]]

外部比较器(定制排序):实现一个Comparator接口,重写compare(t1,t2) 方法中定义比较规则

package com.collection;
​
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
​
//外部比较器:连接comparator
public class TextCompare2 {
    public static void main(String[] args) {
        ArrayList<Student> list=new ArrayList();
        list.add(new Student("zs",189.3,19));
        list.add(new Student("ls",156.2,20));
        list.add(new Student("wy",190.2,15));
        System.out.println(list);
        Collections.sort(list,new Text1());//根据年龄升序
        System.out.println(list);
        Collections.sort(list,new Text2());//根据身高降序
        System.out.println(list);
    }
}
​
//外部比较器
class Text1 implements Comparator<Student>{
    //根据年龄升序
    @Override
    public int compare(Student o1, Student o2) {
        
        return o1.getAge()-o2.getAge();
    }
    
}
//外部比较器
class Text2 implements Comparator<Student>{
    //根据身高降序
    @Override
    public int compare(Student o1, Student o2) {
        
        return (int) (o2.getHeight()-o1.getHeight());
    }
    
}
​

三、Lambda

使用Lambda简化匿名内部类,java8提供了lambda表达式。

  • 使用前提:函数式接口

  • 函数式接口: 只有一个必须要重写的抽象方法的接口

  • 检查函数式接口:@FunctionalInterface

  • 组成结构:()->{}

  • () :要重写的抽象方法的参数列表

  • -> :lambda符号,箭头符号,箭头函数,具有上下文推到作用

  • {} :定义抽象方法的方法体

public class LambdaDemo04 {
    public static void main(String[] args) {
        //r存储Run接口的一个没有名字的实现类对象,存储这个对象的地址
        /*Run r=new Run(){
​
            @Override
            public void run() {
                System.out.println("边被单词边跑步...");
            }
            
        };
        r.run();*/
        //Lambda用来简化匿名内部类
        /*Run r=()->{
                System.out.println("边笑边跑步...");
            };
            
        r.run();*/
        
        //如果方法体只有一句,前后{}可以省略
        //Run r=(int x,int y)->System.out.println("边笑边跑步..."+x+y);
        //如果方法有参数,参数的数据类型可以省略
        //Run r=(x,y)->System.out.println("边笑边跑步..."+x+y);
        
        //当参数列表的参数只有一个,前后的()可以省略
        //Run r= x ->System.out.println("边笑边跑步..."+x);
        
        ////当方法体只有一个语,并且是return语句,return和前后{}可以一起省略
        Run r= x ->"哈哈";
        System.out.println(r.run(1));;
    }
}
​
@FunctionalInterface
interface Run{//接口
    //抽象方法
    String run(int x);
}

 

发布了4 篇原创文章 · 获赞 0 · 访问量 21
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览