IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【数据结构】-【debug】-【jdk9新特性】 -> 正文阅读

[数据结构与算法]【数据结构】-【debug】-【jdk9新特性】

数据结构

一、数据存储的常用结构:栈 队列 数组 链表 红黑树
二、栈stack:先进后出 入口和出口在集合的同一侧
三、队列:先进先出 入口和出口在集合的两侧
四、数组:

  1. 查询快:数组的地址是连续的 我们通过数组的首地址可以找到数组 通过数组的索引可以快速查找某一个元素
  2. 增删慢:数组的长度是固定的 我们想要增加/删除一个元素 必须创建一个新数组 把源数组的数据复制过来。假设定义了一个数组:int[] arr = {1,2,3,4};要把数组中索引是3的元素删除 必须创建一个新的数组,长度是源数组的长度-1 把源数组的其他元素复制到新数组中 把新数组的地址赋值给变量arr 源数组会在内存中被销毁(垃圾回收)。在堆内存中 频繁的创建数组 复制数组中的元素 销毁数组 效率低下

五、链表:

  1. 查询慢:链表中地址不是连续的 每次查询元素都必须从头开始查询
  2. 增删快:链表结构 增加/删除一个元素 对链表的整体结构没有影响 所以增删快
  3. 链表中每一个元素也称之为一个节点 一个节点包含了一个数据源(存储数组)两个指针域(存储地址)
  4. 链表结构:一个链表包含三部分 第一部分存放自己的地址 第二部分存储数据 第三部分存储下一个节点的地址
  5. 分类:
    (1)单向链表:链表中只有一条链子 不能保证元素的顺序(存储元素和取出元素的顺序有可能不一致)
    (2)双向链表:链表中有两条链子 有一条链子是专门记录元素的顺序 是一个有序的集合

六、红黑树:

  1. 约束:
    (1)节点可以是红色的也可以是黑色的
    (2)根节点是黑色的
    (3)叶子节点(空节点)是黑色的
    (4)每个红色的节点的子节点都是黑色的
    (5)任何一个节点到其每一个叶子节点的所有路径山黑色节点数相同
  2. 特点:趋近于平衡树 查询的速度非常快 查询叶子节点最大次数和最小次数不能超过2倍
public class Stack {}

java.util.list

一、java.util.list接口继承了Collection接口
二、List接口的特点:

  1. 有序的集合 存储元素和取出元素的顺序是一致的 存储123 取出123
  2. 有索引 包含了一些带索引的方法
  3. 允许存储重复的元素
    三、List接口中带索引的方法(特有):
  4. public void add(int index,E element):将制定的元素添加到该集合中的指定位置上
  5. public E get(int index):返回集合中指定位置的元素
  6. public E remove(int index):移除列表中指定位置的元素 返回的是被移除的元素
  7. public E set(int index,E element):用指定元素替换集合中指定位置的元素 返回值的更新前的元素

注意:操作索引的时候 一定要防止索引越界异常

四、list集合的实现类:

  1. ArrayList集合:此实现不是同步的 是多线程的
  2. LinkedList集合
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListClass {
	public static void main(String[] args) {
		//创建一个List集合对象 多态
		List<String> list = new ArrayList<String>();
		//使用add方法往集合中添加元素
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		list.add("a");
		//打印集合
		System.out.println(list);//[a, b, c, d, a] 不是地址 重写了toString
		
		//public void add(int index,E element):将制定的元素添加到该集合中的指定位置上
		//在c和d之间添加一个itheima
		list.add(3,"itheima");
		System.out.println(list);//[a, b, c, itheima, d, a]
		
		//public E remove(int index):移除列表中指定位置的元素 返回的是被移除的元素
		//移除c元素
		String remoString = list.remove(2);
		System.out.println("被移除的元素:" + remoString);//被移除的元素:c
		System.out.println(list);//[a, b, itheima, d, a]
		
		//public E set(int index,E element):用指定元素替换集合中指定位置的元素 返回值是被替换的元素
		//把最后一个a替换成A
		String setString = list.set(4, "A");
		System.out.println("被替换的元素:" + setString);//被替换的元素:a
		System.out.println(list);//[a, b, itheima, d, A]
		
		//list集合遍历有三种方式
		//使用普遍的for循环
		System.out.println("使用for循环遍历集合:================================================");
		for (int i = 0; i < list.size(); i++) {
			//public E get(int index):返回集合中指定位置的元素
			String string = list.get(i);
			System.out.println(string);
		}
		//使用迭代器遍历集合
		System.out.println("使用迭代器遍历集合:================================================");
		Iterator<String> iterator = list.iterator();
		while (iterator.hasNext()) {
			String string = (String) iterator.next();
			System.out.println(string);
		}
		//使用增强for循环
		System.out.println("使用增强for循环遍历集合:================================================");
		for (String string : list) {
			System.out.println(string);
		}
	}
}

java.util.Set

一、java.util.Set接口继承了Collection接口
二、Set接口的特点:

  1. 不允许存储重复的元素
  2. 没有索引 没有带索引的方法 也不能使用普通的for循环遍历

三、java.util.HashSet集合实现了Set接口
四、HashSet的特点:

  1. 不允许存储重复的元素
  2. 没有索引 没有带索引的方法 也不能使用普通的for循环遍历
  3. 是一个无序的集合 存储元素和取出元素的顺序有可能不一致
  4. 底层是一个哈希表结构(哈希表结构的特点:查询的速度非常快)
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetClass {
	public static void main(String[] args) {
		Set<Integer> set = new HashSet<Integer>();
		//使用add方法往集合中添加元素
		set.add(1);
		set.add(3);
		set.add(2);
		set.add(1);
		
		//使用迭代器遍历set集合
		System.out.println("使用迭代器遍历set集合:=======================");
		Iterator<Integer> iterator = set.iterator();
		while (iterator.hasNext()) {
			Integer integer = (Integer) iterator.next();
			System.out.println(integer);//1,2,3
		}
		//使用增强for遍历set集合
		System.out.println("使用增强for遍历set集合:=======================");
		for (Integer integer : set) {
			System.out.println(integer);//1,2,3
		}
	}
}

五、Set集合不允许重复存储元素的前提:存储的元素必须重写hashCode方法和equals方法

import java.util.HashSet;
public class SetClass2 {
	public static void main(String[] args) {
		//创建HashSet集合对象
		HashSet<String> set = new HashSet<String>();
		String s1 = new String("abc");
		String s2 = new String("abc");
		set.add(s1);
		set.add(s2);
		set.add("重地");
		set.add("通话");
		set.add("abc");
		System.out.println(set);//[重地, 通话, abc]
	}
}

Set集合在调用add方法时 add方法会调用元素的hashCode方法和equals方法 判断元素是否重复,执行以上代码的过程:

  1. 先在堆内存中开辟一段空间 大小为16
  2. 执行set.add(s1):add方法会调用s1的hashCode方法 计算字符串"abc"的哈希值 计算结果为96354,然后在集合中找有没有96354这个哈希值的元素 发现没有 就会把s1存储到刚才开辟的空间中 索引为0的位置
  3. 执行set.add(s2):add方法会调用s2的hashCode方法 计算字符串"abc"的哈希值 计算结果为96354,然后在集合中找有没有96354这个哈希值的元素 发现有(此时发生哈希冲突),s2会调用equals方法和哈希值相同的元素进行比较,s2.equals(s1)返回true,两个元素的哈希值相同 equals方法返回true 认定两个元素相同 就不会把s2存储到集合中
  4. set.add("重地"):add方法会调用"重地"的hashCode方法 计算字符串"重地"的哈希值 计算结果为1179395,然后在集合中找有没有1179395这个哈希值的元素 发现没有 就会把"重地"存储到刚才开辟的空间中 索引为2的位置
  5. set.add("通话"):add方法会调用"通话"的hashCode方法 计算字符串"通话"的哈希值 计算结果为1179395,然后在集合中找有没有1179395这个哈希值的元素 发现有(此时发生哈希冲突),"通话"会调用equals方法和哈希值相同的元素进行比较,"通话".equals("重地")返回false,两个元素的哈希值相同 equals方法返回false 认定两个元素不同 就会把"通话"存储到集合中 索引为2的位置

六、HashSet存储自定义类型元素:

  1. set集合保证元素唯一 :存储的元素(String Integer …… Person Student ……)必须重写hashCode方法和equals方法
  2. 要求:同名同年龄的人视为同一个人 只能存储一次
import java.util.HashSet;
public class HashSetSavePerson {
	public static void main(String[] args) {
		//创建HashSet集合存储People
		HashSet<People> set = new HashSet<People>();
		People p1 = new People("小美女", 18);
		People p2 = new People("小美女", 18);
		People p3 = new People("小美女", 19);
		//People里只重写了toString方法
		System.out.println(p1.hashCode());//366712642   People里重写了toString hashCode equals:23684579
		System.out.println(p2.hashCode());//1829164700  People里重写了toString hashCode equals:23684579
		System.out.println(p1 == p2);//false  People里重写了toString hashCode equals:false
		System.out.println(p1.equals(p2));//false  People里重写了toString hashCode equals:true

		//系统认为p1 p2哈希值不同 地址不同 内容也不同 所以p1 p2不同 所以把他们都存储到了集合中
		set.add(p1);
		set.add(p2);
		set.add(p3);
		System.out.println(set);//[People{name='小美女',age=19}, People{name='小美女',age=18}, People{name='小美女',age=18}]
		//People里重写了toString hashCode equals:[People{name='小美女',age=18}, People{name='小美女',age=19}]
	}
}

public class People {
	private String nameString;
	private int age;
	
	@Override
	public String toString() {
		return "People{" + "name='" + nameString  + '\'' + ",age=" + age + '}';
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((nameString == null) ? 0 : nameString.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;
		People other = (People) obj;
		if (age != other.age) return false;
		if (nameString == null) {
			if (other.nameString != null) return false;
		} else if (!nameString.equals(other.nameString)) return false;
		return true;
	}

	public String getNameString() {return nameString;}
	public void setNameString(String nameString) {this.nameString = nameString;}
	public int getAge() {return age;}
	public void setAge(int age) {this.age = age;}
	public People(String nameString, int age) {
		super();
		this.nameString = nameString;
		this.age = age;
	}
	public People() {super();}
}

java.util.LinkedHashSet

一、java.util.LinkedHashSet集合继承了HashSet集合
二、LinkedHashSet特点:底层是一个哈希值(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序) 保证元素有序

import java.util.HashSet;
import java.util.LinkedHashSet;
public class LinkedHashSetClass {
	public static void main(String[] args) {
		HashSet<String> set = new HashSet<String>();
		set.add("www");
		set.add("abc");
		set.add("abc");
		set.add("itcast");
		System.out.println(set);//[abc, www, itcast] 无序 不允许重复
		
		LinkedHashSet<String> link = new LinkedHashSet<String>();
		link.add("www");
		link.add("abc");
		link.add("abc");
		link.add("itcast");
		System.out.println(link);//[www, abc, itcast] 有序 不允许重复
	}
}

java.util.LinkedList

一、LinkedList集合:List接口的链表实现 该实现不是同步的 意味着是多线程的 多线程的速度快
二、java.util.LinkedList集合继承了List接口
三、LinkedList集合特点:

  1. 底层是一个链表结构:查询慢 增删快
  2. 里面包含了大量操作首尾元素的方法
  3. 使用LinkedList集合特有的方法不能使用多态

四、常用方法:

  1. public void addFirst(E e):将指定元素插入此列表的开头
  2. public void addLast(E e):将指定元素添加到此列表的结尾
  3. public void push(E e):将元素推入此列表所表示的堆栈
  4. public E getFirst():返回此列表的第一个元素
  5. public E getLast():返回此列表的最后一个元素
  6. public E removeFirst():移除并返回此列表的第一个元素
  7. public E removeLast():移除并返回此列表的最后一个元素
  8. public E pop():从此列表所表示的的堆栈处弹出一个元素
  9. public boolean isEmpty():如果列表不包含元素 则返回true
import java.util.LinkedList;
public class LinkedListClass {
	public static void main(String[] args) {
		show01();
		show02();
		show03();
	}

	/*
	 * public E removeFirst():移除并返回此列表的第一个元素
	 * public E removeLast():移除并返回此列表的最后一个元素
	 * public E pop():从此列表所表示的的堆栈处弹出一个元素 相当于removeFirst方法
	 */
	private static void show03() {
		//创建LinkedList集合对象
		LinkedList<String> linkedList = new LinkedList<String>();
		//使用add方法往集合中添加元素
		linkedList.add("a");
		linkedList.add("b");
		linkedList.add("c");
		
		String firString = linkedList.pop();
		//String firString = linkedList.removeFirst();等效于上条语句
		System.out.println("被移除的第一个元素:" + firString);
		String laString = linkedList.removeLast();
		System.out.println("被移除的第二个元素:" + laString);
		System.out.println(linkedList);
	}

	/*
	 * public E getFirst():返回此列表的第一个元素
	 * public E getLast():返回此列表的最后一个元素
	 */
	private static void show02() {
		//创建LinkedList集合对象
		LinkedList<String> linkedList = new LinkedList<String>();
		//使用add方法往集合中添加元素
		linkedList.add("a");
		linkedList.add("b");
		linkedList.add("c");
/*
 * 若在此处添加语句:
 * linked.clear();//清空集合中的元素 再获取集合中的元素(使用getFirst方法或者getLast方法)会抛出异常:
 * NoSuchElementException 即 如果在linked.clear();语句后面写:
 * String firString = linkedList.getFirst();
 * System.out.println(firString);//a
 * String laString = linkedList.getLast();
 * System.out.println(laString);//c
 * 会报错 为了解决这个问题 可以将以上四行代码优化为:
 * if(!linkedList.isEmpty(){//使用isEmpty方法:public boolean isEmpty():如果列表不包含元素 则返回true
 * String firString = linkedList.getFirst();
 * System.out.println(firString);//a
 * String laString = linkedList.getLast();
 * System.out.println(laString);//c
 * }
 */
		String firString = linkedList.getFirst();
		System.out.println(firString);//a
		String laString = linkedList.getLast();
		System.out.println(laString);//c
	}

	/*
	 * public void addFirst(E e):将指定元素插入此列表的开头
	 * public void addLast(E e):将指定元素添加到此列表的结尾 等效于add方法
	 * public void push(E e):将元素推入此列表所表示的堆栈 等效于addFirst方法
	 */
	private static void show01() {
		//创建LinkedList集合对象
		LinkedList<String> linkedList = new LinkedList<String>();
		//使用add方法往集合中添加元素
		linkedList.add("a");
		linkedList.add("b");
		linkedList.add("c");
		System.out.println(linkedList);//[a, b, c]
		
		//linkedList.addFirst("www");这条语句和下一条语句一样
		linkedList.push("www");
		System.out.println(linkedList);//[www, a, b, c]
		
		linkedList.addLast("com");
		System.out.println(linkedList);//[www, a, b, c, com]
	}
}

哈希值

一、哈希值:是一个十进制的整数 由系统随机给出(就是对象的地址值 是一个逻辑地址 是模拟出来得到的地址 不是数据实际存储的物理地址)
二、在Object类有个方法 可以获取对象的哈希值:int hashCode():返回该对象的哈希值
三、hashCode方法的源码:public native int hashCode();
native:代表该方法调用的是本地操作系统的方法
四、HashSet集合存储数据的结构(哈希表):

  1. JDK1.8之前 哈希表 = 数组 + 链表
  2. JDK1.8之后 哈希表 = 数组 + 链表 但是在链表中用到了红黑树 红黑树可以提高查询的速度 也就是 哈希表 = 数组 + 红黑树

五、哈希表特点:

  1. 查询快
  2. 初始容量为16
  3. 数组结构:把元素进行了分组 相同哈希值的元素是一组 链表/红黑树结构把相同哈希值的元素连接到一起
  4. 存储数据到集合中 先计算数据的哈希值
  5. 若同一个哈希值下包含的数据大于8个(小于8个数据在内存中以链表的形式存放)为了提高查询速度 就会将数据由链表转换成红黑树
public class HashCode {
	public static void main(String[] args) {
		//Person类继承了Object类 所以可以使用Object类的hasCode方法
		Person p1 = new Person();
		int h1 = p1.hashCode();
		System.out.println(h1);//366712642 重写之后此处输出1
		 
		Person p2 = new Person();
		int h2 = p2.hashCode();
		System.out.println(h2);//1829164700 重写之后此处输出1
		
		/*
		 * toString方法的源码:
		 * return getClass().getName() + "@" + integer.toHexString(hashCode());
		 */
		System.out.println(p1);//Person@15db9742是366712642的十六进制表示形式  重写之后此处输出Person@1
		System.out.println(p2);//Person@6d06d69c是1829164700的十六进制表示形式 重写之后此处输出Person@1
		System.out.println(p1 == p2);//false
		
		/*
		 * String类的哈希值:
		 * String类重写了Object类的hashCode方法
		 */
		String s1 = new String("abc");
		String s2 = new String("abc");
		System.out.println(s1.hashCode());//96354
		System.out.println(s2.hashCode());//96354

		//注意!“重地”和“通话”内容不一样但是哈希值一样 这是个例外
		System.out.println("重地".hashCode());//1179395
		System.out.println("通话".hashCode());//1179395
	}
}
public class Person extends Object{
	//重写hashCode方法
	@Override
	public int hashCode() {return 1;}
}

Map

一、Map(K,V):将键映射到值的对象 一个映射不能包含重复的键 每个键最多只能映射到一个值 K代表键的类型 V代表值的类型
二、Collection中的集合称为单列集合 元素是孤立存在的(理解为单身),向集合中存储元素只能一个一个存储
三、Map中的集合称为双列集合 元素是成对存在的(理解为夫妻) 每个元素由键与值两部分组成 通过键可以找到所对应的值
四、Map中的集合的特点:

  1. 键是唯一的 值可以重复
  2. 键和值一一映射 一个键对应一个值
  3. 靠键维护他们的关系

五、总结Map集合的特点:

  1. Map集合是一个双列集合 一个元素包含两个值(一个key 一个value)
  2. Map集合中的元素 key和value的数据类型可以相同 也可以不同
  3. Map集合中的元素 key是不允许重复的 value是可以重复的
  4. Map集合中的元素 key和value是一一对应

Map集合的遍历方式

一、Map集合的第一种遍历方式:通过键找值的方式

  1. Map集合中的方法:Set<K> keySet():返回此映射中包含的键的Set视图
  2. 实现步骤:
    (1)使用map集合中的方法keyset(),把map集合所有的key取出来 存储到一个set集合中
    (2)遍历set集合 获取map集合中的每一个key
    (3)通过map集合中的方法get(key) 通过key找到value
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class KeySet {
	public static void main(String[] args) {
		//创建Map集合对象 使用多态
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("赵丽颖", 168);
		map.put("杨颖", 165);
		map.put("林志玲", 178);
		
		//(1)使用map集合中的方法keyset(),把map集合所有的key取出来 存储到一个set集合中
		Set<String> set = map.keySet();
		//(2)遍历set集合 获取map集合中的每一个key
		//使用迭代器遍历set集合
		Iterator<String> iterator = set.iterator();
		while (iterator.hasNext()) {
			String key = (String) iterator.next();
			//(3)通过map集合中的方法get(key) 通过key找到value
			Integer valueInteger = map.get(key);
			System.out.println(key + "=" + valueInteger);
		}
		System.out.println("也可以使用增强for遍历set集合:-------------------------------------------------------------------------------");
		for (String key : set) {
			//(3)通过map集合中的方法get(key) 通过key找到value
			Integer valueInteger = map.get(key);
			System.out.println(key + "=" + valueInteger);
		}
	}
}

二、map集合遍历的第二种方式:使用entry对象遍历

  1. map集合中的方法:Set<Map.Entry<K,V>> entrySet()返回此映射中包含的映射关系的Set视图
  2. 实现步骤:
    (1)使用Map集合中的方法entrySet() 把map集合中多个Entry对象取出来 存储到一个Set集合中
    (2)遍历Set集合 获取每一个Entry对象
    (3)使用Entry对象中的方法getKey()getValue()获取键与值
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class EntrySet {
	public static void main(String[] args) {
		//创建Map集合对象 使用多态
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("赵丽颖", 168);
		map.put("杨颖", 165);
		map.put("林志玲", 178);
		//(1)使用Map集合中的方法entrySet() 把map集合中多个Entry对象取出来 存储到一个Set集合中
		Set<Map.Entry<String, Integer>> set = map.entrySet();
		//(2)遍历Set集合 获取每一个Entry对象
		//使用迭代器遍历Set集合
		Iterator<Map.Entry<String, Integer>> iterator = set.iterator();
		while (iterator.hasNext()) {
			Map.Entry<java.lang.String, java.lang.Integer> entry = (Map.Entry<java.lang.String, java.lang.Integer>) iterator
					.next();
			//(3)使用Entry对象中的方法getKey()和getValue()获取键与值
			String keyString = entry.getKey();
			Integer valueInteger = entry.getValue();
			System.out.println(keyString + "=" + valueInteger);
		}
		//使用增强for循环遍历Set集合
		System.out.println("使用增强for循环遍历Set集合:============================================");
		for (Map.Entry<String, Integer> entry : set) {
			//(3)使用Entry对象中的方法getKey()和getValue()获取键与值
			String keyString = entry.getKey();
			Integer valueInteger = entry.getValue();
			System.out.println(keyString + "=" + valueInteger);
		}
	}
}

java.util.HashTable

一、java.util.HashTable<K,V>集合 implements Map<K,V>接口
二、HashTable:底层也是一个哈希表 是一个线程的安全的集合 是单线程集合 速度慢
HashMap:底层是一个哈希表 是一个线程不安全的集合 是多线程的集合 速度快
三、HashMap集合(之前学得所有的集合):可以存储Null值 null键,HashTable集合不能存储null值 null键
四、HashTable和Vector集合一样 在JDK1.2版本之后被更先进的集合(HashMap ArrayList集合)取代了,HashTable的子类Properties依然活跃在历史的舞台
五、Properties集合是唯一一个和IO流相结合的集合

import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
public class HashTableClass {
	public static void main(String[] args) {
		HashMap<String, String> map = new HashMap<String, String>();
		map.put(null,"a");
		map.put("b",null);
		map.put(null,null);
		System.out.println(map);//{null=null, b=null}
		
		Hashtable<String, String> table = new Hashtable<String, String>();
		//执行以下语句会报错 hashTable不能有null
		table.put(null,"a");
		table.put("b",null);
		table.put(null,null);
		System.out.println(table);
	}
}

HashMap

一、java.util.HashMap<K,V>集合 implements Map<K,V>接口
二、HashMap集合的特点:

  1. HasMap集合底层是哈希表:查询的速度特别的快
    (1)JDK1.8之前:数组+单向链表
    (2)JDK1.8之后:数组+单向链表/红黑树(链表长度超过8):提高查询速度
  2. HasMap集合是一个无序的集合 存储元素和取出元素的顺序有可能不一致

三、java.util.LinkedHashMap<K,V>集合 extends HashMap<K,V>集合

  1. LinkedHashMap<K,V>集合特点:
    (1)LinkedHashMap<K,V>集合底层是哈希表+链表(保证迭代的顺序)
    (2)LinkedHashMap<K,V>集合是一个有序的集合 存储元素和取出元素的顺序是一致的
import java.util.HashMap;
import java.util.Map;
public class MapClass{
	public static void main(String[] args) {
		show01();
		show02();
		show03();
		show04();
	}

	/*boolean containsKey(Object key)判断集合中是否包含指定的键
	 * 包含返回true 不包含返回false
	 */
	private static void show04() {
		//创建Map集合对象 使用多态
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("赵丽颖", 168);
		map.put("杨颖", 165);
		map.put("林志玲", 178);
		boolean b1 = map.containsKey("赵丽颖");
		System.out.println("b1:" + b1);//b1:true
		boolean b2 = map.containsKey("赵颖");
		System.out.println("b2:" + b2);//b2:false
	}

	/*
	 * public V get(Object key):根据指定的键 在map集合中获取对应的值
	 * 返回值:
	 * key存在 返回对应的value值
	 * key不存在 返回null
	 */
	private static void show03() {
		//创建Map集合对象 使用多态
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("赵丽颖", 168);
		map.put("杨颖", 165);
		map.put("林志玲", 178);
		System.out.println(map);//{林志玲=178, 赵丽颖=168, 杨颖=165}
		Integer v1 = map.get("杨颖");
		System.out.println("v1:" + v1);//v1:165
		Integer v2 = map.get("迪丽热巴");
		System.out.println("v2:" + v2);//v1:null
		
	}

	/*public V remove(Object key):把指定的键所对应的键值对元素在map集合中删除 返回被删除元素的值 返回值:V
	 * key存在 v返回被删除的值 key不存在 v返回null
	 */
	private static void show02() {
		//创建Map集合对象 使用多态
		Map<String, Integer> map = new HashMap<String, Integer>();
		map.put("赵丽颖", 168);
		map.put("杨颖", 165);
		map.put("林志玲", 178);
		System.out.println(map);//{林志玲=178, 赵丽颖=168, 杨颖=165}

		Integer v1 = map.remove("林志玲");
		System.out.println("v1:" + v1);//v1:178
		System.out.println(map);//{赵丽颖=168, 杨颖=165}
		
		Integer v2 = map.remove("林志颖");
		System.out.println("v2:" + v2);//v2:null
		System.out.println(map);//{赵丽颖=168, 杨颖=165}

	}

	/*public V put(K key,V value):把指定的键与指定的值添加到Map集合中 返回值是V
	 * 存储键值对的时候(key不重复) 若value不重复 返回值V是null 若value重复 会使用新的value替换map中重复的value 返回被替换的value值
	 */
	
	private static void show01() {
		//创建Map集合对象 使用多态
		Map<String, String> map = new HashMap<String, String>();
		
		String v1 = map.put("李晨", "范冰冰1");
		System.out.println("v1:" + v1);//v1:null
		String v2 = map.put("李晨", "范冰冰2");
		System.out.println("v2:" + v2);//v2:范冰冰1
		System.out.println(map);//{李晨=范冰冰2}
		map.put("冷锋", "龙小云");
		map.put("杨过", "小龙女");
		map.put("尹志平", "小龙女");
		System.out.println(map);//{杨过=小龙女, 尹志平=小龙女, 李晨=范冰冰2, 冷锋=龙小云}
	}
}

HashMap存储自定义类型键值

Map集合保证key是唯一的:作为key的元素必须重写hashCode方法和equals方法 以保证key唯一

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HashMapSavePersonClass {
	public static void main(String[] args) {
		show01();
		show02();
	}

	/*
	 * HashMap存储自定义类型键值
	 * key:Person类型  Person类型就必须重写hashCode方法和equals方法 以保证key唯一
	 * value:String类型  可以重复
	 */
	private static void show02() {
		//创建HashMap集合	
		HashMap<Person,String> map = new HashMap<>();
		//往集合中添加元素
		map.put(new Person("女王", 18),"英国");
		map.put(new Person("秦始皇", 18),"秦国");
		map.put(new Person("普京", 30),"俄罗斯");
		map.put(new Person("女王", 18),"毛里求斯");
		//使用entrySet和增强for循环遍历map集合
		Set<Map.Entry<Person, String>> set = map.entrySet();
		for (Map.Entry<Person, String> entry : set) {
			Person keyPerson = entry.getKey();
			String valueString = entry.getValue();
			System.out.println(keyPerson + "-->" + valueString);
		}
	}

	/*
	 * HashMap存储自定义类型键值
	 * key:String类型  String类重写hashCode方法和equals方法 可保证key唯一
	 * value:Person类型    value可以重复(同名同年龄的人视为同一个人)
	 * 
	 */
	private static void show01() {
		//创建HashMap集合	
		HashMap<String, Person> map = new HashMap<String, Person>();
		//往集合中添加元素
		map.put("北京", new Person("张三",18));
		map.put("上海", new Person("李四",19));
		map.put("广州", new Person("王五",20));
		map.put("北京", new Person("赵六",18));
		//使用KeySet和增强for循环遍历map集合
		Set<String> set = map.keySet();
		for (String key : set) {
			Person valuePerson = map.get(key);
			System.out.println(key + "-->" + valuePerson);
		}
	}
}


public class Person {

	private String nameString ;
	private int age;
	public String getNameString() {
		return nameString;
	}
	public void setNameString(String nameString) {
		this.nameString = nameString;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Person(String nameString, int age) {
		super();
		this.nameString = nameString;
		this.age = age;
	}
	public Person() {
		super();
	}
	@Override
	public String toString() {
		return "Person [nameString=" + nameString + ", age=" + age + "]";
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((nameString == null) ? 0 : nameString.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;
		Person other = (Person) obj;
		if (age != other.age) return false;
		if (nameString == null) {
			if (other.nameString != null) return false;
		} else if (!nameString.equals(other.nameString)) return false;
		return true;
	}	
}

java.util.LinkedHashMap

一、java.util.LinkedHashMap<K,V> entends HashMap<K,V>
二、Map接口的哈希表和链接列表实现 具有可预知的迭代顺序
三、底层原理:哈希值+链表(记录元素的顺序)

import java.util.HashMap;
import java.util.LinkedHashMap;
public class LinkedHashMapClass {
	public static void main(String[] args) {
		HashMap<String, String> map = new HashMap<>();
		map.put("a","a");
		map.put("c","c");
		map.put("b","b");
		map.put("a","d");
		System.out.println(map);//{a=d, b=b, c=c} key不允许重复 是一个无序的集合 最后一行的d把第一行的a替换掉了
		
		LinkedHashMap<String, String> link = new LinkedHashMap<>();
		link.put("a","a");
		link.put("c","c");
		link.put("b","b");
		link.put("a","d");
		System.out.println(link);//{a=d, c=c, b=b}  key不允许重复 是一个有序的集合
	}
}

Debug

一、Debug调试过程:可以让代码逐行执行 查看代码执行的过程 调试程序中出现的bug
二、使用方式:

  1. 在行号的左边 鼠标左键双击 添加断点(建议初学者添加到每个方法的第一行 以后熟悉了,就哪里有bug添加到哪里),然后右键选择Debug执行程序 程序就会停留在添加的第一个断点处
  2. 执行程序:
    (1)step over:逐行执行程序
    (2)step into:进入方法中
    (3)step out:跳出方法
    (4)resume program:跳到下一个断点 如果没有下一个断点 那么就结束程序
    (5)stop:退出debug模式 停止程序
    (6)console:切换到控制台
public class Debug {
	public static void main(String[] args) {
		int a = 10;
		int b = 20;
		int sum = a + b;
		System.out.println(sum);
	}
}

jdk9新特性

一、List接口,set接口,map接口:里面增加了一个静态的方法of 可以给集合一次性添加多个元素:static <E> List<E> of (E...elements)
使用前提:当集合中存储的元素个数已经确定了 不再改变时使用

【注】:

  1. of方法只适用于List接口,set接口,map接口 不适用于接口的实现类
  2. of方法的返回值是一个不能改变的集合 集合不能再使用add put方法添加元素 会抛出异常
  3. Set接口和Map接口在调用of方法的时候 不能有重复的元素 否则会抛出异常
import java.util.List;
import java.util.Map;
import java.util.Set;
public class JDK9 {
	public static void main(String[] args) {
		List<String> list = List.of("a","b","a","c","d");//此处已经确定集合中元素的个数
		System.out.println(list);//[a,b,a,c,d]
		list.add("w");//当集合中存储的元素个数已经确定了 不能再改变 此处会报错:不支持操作异常
		
		Set<String> set = Set.of("a","b","a","c","d");
		System.out.println(set);//错误!Set接口和Map接口在调用of方法的时候 不能有重复的元素 否则会抛出异常:非法参数异常
	}
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-24 18:28:41  更:2022-05-24 18:29:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:49:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码