当前位置:首页>学习笔记>韩顺平java基础集合篇(个人学习笔记)

韩顺平java基础集合篇(个人学习笔记)

  • 2026-03-26 10:15:16
韩顺平java基础集合篇(个人学习笔记)

集合

思维导图

数组(灵活性不足)

a.长度开始时必须指定,而且一旦指定,不能更改

b.保存的必须为同一类型的元素

c.使用数组进行增加元素的示意代码 - 比较麻烦写出 Person 数组扩容示意代码。(数组添加元素麻烦

Java                  Person [] pers = new Person [1];                  per [0]=new Person ();

d.增加新的 Person 对象?

Java                  Person [] pers2 = new Person [pers.length+1]; // 新创建数组                  for (){} // for循环拷贝 pers 数组的元素pers2                  pers2 [pers2.length-1]=new Person ();// 添加新的对象

集合的引出

1.好处:可以动态的保存任意多个对象

2.提供简单造作对象的方法,如add,remove,set,,get等

3.使用集合增删改新元素的代码简介明了

集合体系图(两种,单列(Collection)和双列(Map)集合)

单列集合(Collection有两类:List和Set),存储单个数据元素          

双列集合(又细分为三类),存储键值对元素          

collection接口和常用方法

集合元素遍历

1.迭代器(Iterator)遍历

这是最通用的遍历方式,适用于所有实现了Iterable接口的集合(几乎所有集合都实现了),支持在遍历中安全删除元素。主要用于遍历collection集合中的元素

Java                  import java.util.ArrayList;                  import java.util.Collection;                  import java.util.Iterator;                  public class Test{                  public static void main(String[] args) {                  Collectionlist = new ArrayList<>();          list.add("A");          list.add("B");          list.add("C");          // 获取迭代器          Iteratoriterator = list.iterator();           //使用while遍历           while (iterator.hasNext()) {// 判断是否有下一个元素,iterator.next之前必须先进行//iterator.hashNext()检查;String element = iterator.next(); // 获取下一个元素                  System.out.println(element);                  // 若需要删除元素,使用iterator.remove(),而非集合的remove()                  // if (element.equals("B")) iterator.remove();                  }                  }                  }

2.增强for循环遍历:

Java                  import java.util.List;                  import java.util.ArrayList;                  ...                  List list=new ArrayList                  for(Object obj:list){                  sout(obj);                  }

3.普通for循环遍历

Java                  for(int i=0;i         <list.size();i++){                   </list.size();i++){         sout("对象="+list.get(i));}

快捷键

1.快速写出Iterator的while循环:itit+Enter键

Java                  while (iterator.hasNext()) {                  Object next =iterator.next();                  }

2.显示所有快捷键的快捷键:ctrl+j

以子类实现ArrayList演示。

List接口介绍

单列集合(Collection有两类:List和Set),存储单个数据元素          

List接口是Collection接口的子接口

1.元素有序且可重复:元素的添加顺序与取出顺序一致,允许存入重复元素。

2.支持索引访问:每个元素都对应一个整数型顺序索引,可通过索引直接存取元素。

3.常用的有:Vector, ArrayList, LinkedList等

List常用方法(以ArrayList为例)

1.添加元素

Java                  ...                  import java.util.Arrays;                  import java.util.List;                  ...                  List list=new ArrayList();                  list.add("张三丰");                  list.add("贾宝玉");                  list.add(1,"韩顺平");//在1的位置加入字符串sout("list="+list);List list2=new ArrayList();                  list2.add("Jack");                  list.add("Tom");                  list.addAll(1,list2);//在list的1的位置插入list的元素,其他字符串后移动sout("list="+list);                  // 方式3.2:ArrayList 包装(可修改的 List,推荐)                  ListmutableList = new ArrayList<>(Arrays.asList("北京", "上海", "广州", "深圳"));          mutableList.add("杭州");          // 可以正常添加          // 输出:[北京, 上海, 广州, 深圳, 杭州]          System.out.println(mutableList);          

2.找索引

返回obj对象首次出现的位置

Java                  sout(list.indexOf("Tom"));//返回2

返回obj对象在当前集合中末次出现的位置

Java                  list.add("韩顺平");                  sout(list.lastIndexOf("韩顺平");//返回5

3.remove删除在指定下标位置的元素,并返回此元素

Java                  list.remove(0);                  sout(list);//[jack,tom,韩顺平,贾宝玉,韩顺平]

4.set设置指定位置元素,相当于替换

Java                  list.set(1,"玛丽");、、[jack,玛丽,韩顺平,贾宝玉,韩顺平]

5.list返回指定区间(左闭右开)的集合元素

Java                  List returnList=list.subList(0,2);sout(returnList); //[jack,玛丽]

ArrayList底层结构和源码分析

ArrayList的注意事项

1.ArrayList可以存放一个甚至多个null对象

Java                  ArrayList arrayList=new ArrayList();                  arrayList.add(null);                  arrayList("jack");                  arrayList(null);//[null,jack,null]

2.ArrayList是线程不安全的,底层代码没有synchronized修饰,但是执行效率高

3.ArrayList是由数组实现数据存储的

4.ArrayList基本等同于Vector, 除了ArrayList是线程不安全(执行效率高),在多线程情况下,不建议使用ArrayList

ArrayList底层结构和源码分析

省略此部分

Vector底层结构和源码分析

Vector注意事项

1.Vector底层也是一个对象数组,protected Object[] elementData;

2.Vector是线程同步的,即线程安全的;Vector类的操作方法带有sychronized

Java                  @SuppressWarnings({"all"})                  public class Vector_ {                  public static void main(String[] args) {                  Vector vector = new Vector();                  for (int i = 0; i < 10; i++) {                  vector.add(i);                  }                  }                  }

底层代码——扩容机制(省略)

LinkedList底层结构

一. LinkedList 核心说明提取

1.底层实现LinkedList 底层实现了双向链表双端队列的特点。

2.元素特性可以添加任意元素(元素可重复),包括 null

3.线程安全:线程不安全,没有实现同步。

Java                  public class LinkedList01 {                  public static void main(String[] args) {                  //模拟一个简单的双向链表                  Node jack = new Node("jack");                  Node tom = new Node("tom");                  Node hsp = new Node("老韩");                  //连接三个结点,形成双向链表                  //jack -> tom -> hsp                  jack.next = tom;                  tom.next = hsp;                  //hsp -> tom -> jack                  hsp.pre = tom;                  tom.pre = jack;                  Node first = jack; //让first引用指向jack,就是双向链表的头结点                  Node last = hsp;//让last引用指向hsp,就是双向链表的尾结点                  //演示,从头到尾进行遍历                  System.out.println("===从头到尾进行遍历===");                  while (true) {                  if (first == null) {                  break;                  }                  //输出first信息                  System.out.println(first);                  first = first.next;                  }                  //演示,从尾到头的遍历                  System.out.println("====从尾到头的遍历====");                  while (true) {                  if (last == null) {                  break;                  }                  //输出last信息                  System.out.println(last);                  last = last.pre;                  }                  //演示链表的添加对象/数据,是多么的方便                  //要求:是在 tom -------- 老韩之间,插入一个对象 smith                  //1. 先创建一个Node结点,name就是smith                  Node smith = new Node("smith");                  //下面就把smith加入到双向链表了                  smith.next = hsp;                  smith.pre = tom;                  hsp.pre = smith;                  tom.next = smith;                  //让first再次指向jack                  first = jack; //让first引用指向jack,就是双向链表的头结点                  System.out.println("===从头到尾进行遍历===");                  while (true) {                  if (first == null) {                  break;                  }                  //输出first信息                  System.out.println(first);                  first = first.next;                  }                  }                  }                  //定义一个Node类,Node对象表示双向链表的一个结点                  class Node {                  public Object item; //真正存放数据                  public Node next;//指向后一个结点                  public Node pre;//指向前一个结点                  public Node(Object name) {                  this.item = name;                  }                  public String toString() {                  return "Node name=" + item;                  }                  }                  

LinkList的使用

1.增: add()添加元素

2.删:remove(删除头结点或者指定索引结点

3.改: set() 修改指定索引结点的值

4.查:get()获取指定索引结点的值

5.遍历:迭代器、增强for循环,普通for循环

Java                  import java.util.Iterator;                  import java.util.LinkedList;                  public class LinkedListCRUD {                  public static void main(String[] args) {                   LinkedList linkedList = new LinkedList();linkedList.add(1);                  linkedList.add(2);                  linkedList.add(3);                  System.out.println("linkedList=" + linkedList);                  // 演示删除结点(默认删除第一个结点)                  linkedList.remove();// linkedList.remove(2); // 按索引删除                  System.out.println("linkedList=" + linkedList);                  // 修改某个结点对象                  linkedList.set(1, 999);System.out.println("linkedList=" + linkedList);                  // 得到某个结点对象(get(1) 获取双向链表的第二个对象)                  Object o = linkedList.get(1);System.out.println(o); // 999                  // 因为LinkedList实现了List接口,遍历方式                  // 1. 迭代器遍历                  System.out.println("===LinkedList遍历迭代器===");                  Iterator iterator = linkedList.iterator();while (iterator.hasNext()) {//先判断是否存在下一个再继续Object next = iterator.next();                  System.out.println("next=" + next);                  }                  // 2. 增强for循环遍历                  System.out.println("===LinkedList遍历迭代器增强for===");                  for (Object o1 : linkedList) {                  System.out.println("o1=" + o1);                  }                  // 3. 普通for循环遍历                  System.out.println("===LinkedList遍历普通for===");                  for (int i = 0; i < linkedList.size(); i++) {                  System.out.println(linkedList.get(i));                  }                  }                  }

ArrayList和LinkedList的比较总结

Set接口介绍(继承Collection接口)

基本介绍:

核心特性

无序:元素添加顺序取出顺序不一致,不支持索引访问。

不允许重复:集合中不能存在重复元素,因此最多只能包含一个 null

继承与实现

继承自 Collection 和 Iterable 接口。

已知子接口:NavigableSetSortedSet

已知实现类:AbstractSetConcurrentSkipListSetCopyOnWriteArraySetEnumSetHashSetJobStateReasonsLinkedHashSetTreeSet 等。

常用实现类HashSetLinkedHashSetTreeSet

常用方法

Set 接口是 Collection 接口的子接口,因此常用方法与 Collection 接口完全一致

导入包:

Java                  import java.util.Set;//或者万能包                  

Java                  set.remove(null);

1.迭代器遍历:

2.增强for循环遍历

3.Set接口对象,不能通过索引获取,所以不能使用普通for循环遍历

遍历方式(以上)

与 Collection 接口的遍历方式一致:

a.迭代器(Iterator)

b.增强 for 循环(foreach)

c.不支持通过索引的方式遍历 / 获取元素(因为 Set 无序且无索引)。

分类:HashSet和TreeSet,继承Set接口,Set又继承collection接口

HashSet

一.基本介绍

TypeScript                  @SuppressWarnings({"all"})                  public class HashSet_ {                  public static void main(String[] args) {                  //1. 构造器HashSet走的源码(底层源码)                  /*                  public HashSet() {  //HashSet实际上是HashMapmap = new HashMap<>();                  }                  2. HashSet可以存放一个null,但只能有一个null*/                  Set hashSet = new HashSet();                  hashSet.add(null);                  hashSet.add(null);                  System.out.println("hashSet="+hashSet);                  }                  }

1.验证HashSet不允许有重复元素

C++                  import java.util.HashSet;                  public class HashSet01 {                  public static void main(String[] args) {                  HashSet set = new HashSet();                  // 说明                  // 1. 在执行add方法后,会返回一个boolean值                  // 2. 如果添加成功,返回 true,否则返回false                  System.out.println(set.add("john"));// T                  System.out.println(set.add("lucy"));// T                  System.out.println(set.add("john"));// F(重复元素,添加失败)                  System.out.println(set.add("jack"));// T                  System.out.println(set.add("Rose"));// T                  set.remove("john");                  System.out.println("set=" + set);                  }                  }

2.HashSet不允许有重复元素,为什么直接new一个Dog对象就可以重复呢?而new一个String对象却不可以重复

TypeScript                  import java.util.HashSet;                  // 定义了Dog类                  class Dog {                  private String name;                  public Dog(String name) {                  this.name = name;                  }                  // 为了打印美观,补充toString方法                  @Override                  public String toString() {                  return "Dog{name='" + name + "'}";                  }                  }                  public class HashSetDemo {                  public static void main(String[] args) {                  HashSet set = new HashSet();                  System.out.println("set=" + set); // 0                  // 4 HashSet 不能添加相同的元素/数据?                  set.add("lucy"); // 添加成功                  set.add("lucy"); // 加入不了(重复元素)                  set.add(new Dog("tom")); // OK                  set.add(new Dog("tom")); // OK(未重写equals和hashCode,视为不同对象)                  System.out.println("set=" + set);                  // 再加深一下。非常经典的面试题。                  // 看源码,做分析                  set.add(new String("hsp")); // ok                  set.add(new String("hsp")); // 加入不了(String重写了equals和hashCode,视为相同对象)                  System.out.println("set=" + set);                  }                  }

二.HashSet底层机制说明

1.HashSet底层是HashMap,HashMap底层是(数组+链表+红黑树)

想像模拟一下哈希表:有一个数组,每个数组元素都单独带有一条链表,数组的大小就是链表的条数

构造器快捷键:

Alt + Insert(Windows/Linux)

2.代码演示(哈希表数据存储效率高效

Java                  @SuppressWarnings({"all"})                  // 结点类:存储数据并指向下一个结点,用于形成链表                  class Node {                  Object item; // 存放数据                  Node next;// 指向下一个结点                  // 带参构造器,初始化结点数据和下一个结点引用                  public Node(Object item, Node next) {                  this.item = item;                  this.next = next;                  }                  }                  public class HashSetStructure {                  public static void main(String[] args) {                  // 模拟HashSet/HashMap的底层结构:数组+链表                  // 1. 创建Node类型的数组(也称为"表"),初始容量为16                  Node[] table = new Node[16];                  System.out.println("table=" + table);                  // 3. 创建结点并挂载到数组                  // 创建john结点,挂载到数组索引2的位置                  Node john = new Node("john", null);                  table[2] = john;                  // 创建jack结点,挂载到john结点之后                  Node jack = new Node("jack", null);                  john.next = jack;                  // 创建Rose结点,挂载到jack结点之后                  Node rose = new Node("Rose", null);                  jack.next = rose;                  // 创建lucy结点,挂载到数组索引3的位置                  Node lucy = new Node("lucy", null);                  table[3] = lucy;                  System.out.println("table=" + table);                  }                  }

3.为什么new一个重复Dog对象可以插入,而new一个新的String对象却不可以(面试题

HashSet 底层是 HashMap

1)添加一个元素时,先得到 hash 值 → 转换成索引值

2)找到存储数据表 table,检查该索引位置是否已存在元素

3)如果没有元素,直接将新元素加入(插入元素到链表中)

5)如果已有元素:

调用 equals() 进行比较

若 equals 返回 true(元素相同),则放弃添加

若 equals 返回 false(元素不同),则将新元素添加到链表末尾

6) Java 8 树化规则(面试重点)

当一条链表的元素个数超过 TREEIFY_THRESHOLD(默认值为 8

并且数组 table 的大小 ≥ MIN_TREEIFY_CAPACITY(默认值为 64

满足以上两个条件时,该链表会被转换为红黑树(树化),以提升查询效率

关键补充说明

hash → 索引:hash 值并非直接作为索引,而是通过 (n - 1) & hash(n 为数组长度)计算得到数组下标,保证索引落在数组范围内。

equals 比较:先比较 hashCode(),再比较 equals(),只有两者都相同时,才判定为重复元素。

树化目的:链表过长时查询效率会退化到 O (n),红黑树可将查询效率优化到 O (log n)。

三. HashSet底层源码

靠理解,这里省略,请前往韩顺平java基础视频521~524理解

四.课堂练习:灵活使用HashSet

TypeScript                  import java.util.HashSet;                  import java.util.Objects;                  class Employee {                  private String name;                  private int age;                  // 构造器                  public Employee(String name, int age) {                  this.name = name;                  this.age = age;                  }                  // Getter & Setter                  public String getName() {                  return name;                  }                  public void setName(String name) {                  this.name = name;                  }                  public int getAge() {                  return age;                  }                  public void setAge(int age) {                  this.age = age;                  }                  // 重写equals:name和age都相同时视为同一员工                  @Override                  public boolean equals(Object o) {                  if (this == o) return true;                  if (o == null || getClass() != o.getClass()) return false;                  Employee employee = (Employee) o;                  return age == employee.age && Objects.equals(name, employee.name);                  }                  // 重写hashCode:基于name和age生成哈希值,保证相同员工哈希值一致                  @Override                  public int hashCode() {                  return Objects.hash(name, age);                  }                  // 重写toString:方便打印查看                  @Override                  public String toString() {                  return "Employee{name='" + name + "', age=" + age + "}";                  }                  }                  public class HashSetExercise {                  public static void main(String[] args) {                  HashSethashSet = new HashSet<>();          // 添加员工对象          hashSet.add(new Employee("milan", 18)); // 添加成功          hashSet.add(new Employee("smith", 28)); // 添加成功          hashSet.add(new Employee("milan", 18)); // 添加失败(与第一个对象name和age相同)          // 打印集合,验证去重效果          System.out.println("hashSet=" + hashSet);          }          }

1.最终集合中只包含 2 个 员工对象,第三个 new Employee("milan", 18) 因与第一个对象 name 和 age 完全相同,被 HashSet 判定为重复元素而拒绝添加。

2.去重关键HashSet 去重依赖 hashCode() 和 equals() 方法,必须同时重写才能实现自定义对象的去重逻辑。

3.哈希计算Objects.hash(name, age) 会根据 name 和 age 生成哈希值,保证相同属性的对象哈希值一致。

4.相等判断equals() 方法中同时比较 age 和 name,只有两者都相等时才认为是同一个员工。

TypeScript                  import java.util.HashSet;                  import java.util.Objects;                  /**                     * 自定义日期类                     */                  class MyDate {                  private int year;                  private int month;                  private int day;                  public MyDate(int year, int month, int day) {                  this.year = year;                  this.month = month;                  this.day = day;                  }                  // Getter                  public int getYear() { return year; }                  public int getMonth() { return month; }                  public int getDay() { return day; }                  // 重写equals:年月日都相同视为同一日期                  @Override                  public boolean equals(Object o) {                  if (this == o) return true;                  if (o == null || getClass() != o.getClass()) return false;                  MyDate myDate = (MyDate) o;                  return year == myDate.year && month == myDate.month && day == myDate.day;                  }                  // 重写hashCode:基于年月日生成哈希值                  @Override                  public int hashCode() {                  return Objects.hash(year, month, day);                  }                  // 重写toString,方便打印                  @Override                  public String toString() {                  return year + "年" + month + "月" + day + "日";                  }                  }                  /**                     * 员工类                     */                  class Employee {                  private String name;// 姓名                  private double sal;// 薪资                  private MyDate birthday; // 生日                  // 构造器                  public Employee(String name, double sal, MyDate birthday) {                  this.name = name;                  this.sal = sal;                  this.birthday = birthday;                  }                  // Getter & Setter                  public String getName() { return name; }                  public void setName(String name) { this.name = name; }                  public double getSal() { return sal; }                  public void setSal(double sal) { this.sal = sal; }                  public MyDate getBirthday() { return birthday; }                  public void setBirthday(MyDate birthday) { this.birthday = birthday; }                  // 重写equals:name和birthday都相同时,视为同一员工                  @Override                  public boolean equals(Object o) {                  if (this == o) return true;                  if (o == null || getClass() != o.getClass()) return false;                  Employee employee = (Employee) o;                  return Objects.equals(name, employee.name) && Objects.equals(birthday, employee.birthday);                  }                  // 重写hashCode:基于name和birthday生成哈希值                  @Override                  public int hashCode() {                  return Objects.hash(name, birthday);                  }                  // 重写toString:方便打印查看集合内容                  @Override                  public String toString() {                  return "Employee{name='" + name + "', sal=" + sal + ", birthday=" + birthday + "}";                  }                  }                  /**                     * 测试类                     */                  public class HashSetExercise2 {                  public static void main(String[] args) {                  HashSethashSet = new HashSet<>();          // 创建日期对象          MyDate date1 = new MyDate(1990, 1, 1);          MyDate date2 = new MyDate(1995, 5, 20);          MyDate date3 = new MyDate(1990, 1, 1); // 与date1日期相同          // 添加员工对象          hashSet.add(new Employee("milan", 5000, date1));// 添加成功          hashSet.add(new Employee("smith", 8000, date2));// 添加成功          hashSet.add(new Employee("milan", 6000, date3));// 添加失败(name和birthday与第一个一致)          // 打印集合,验证去重效果          System.out.println("hashSet=" + hashSet);          }          }

运行:

Java                  hashSet=[Employee{name='milan', sal=5000.0, birthday=1990年1月1日}, Employee{name='smith', sal=8000.0, birthday=1995年5月20日}]

LinkedHashSet:

LinkedHashSet接口继承HashSet接口,它和HashSet最大的区别就在它是双向的,而HashSet是单向的

1.继承关系LinkedHashSet 是 HashSet 的子类。

2.底层结构:底层基于 LinkedHashMap 实现,维护 数组 + 双向链表 的数据结构哈希表(数组 + 链表 / 红黑树)+ 双向链表

双向链表有 head(头节点)和 tail(尾节点)指针,每个节点包含 pre(前驱)和 next(后继)属性

3.存储与顺序

根据元素的 hashCode 值决定存储位置。

用链表维护元素次序(图),保证元素以插入顺序保存即取出和存储进去的顺序是一样的

C++                  Set set = new LinkedHashSet();                  set.add(new String("AA"));                  set.add(456);                  set.add(456); // 重复元素,不会被添加                  set.add(new Customer("刘", 1001));                  set.add(123);                  set.add("HSP");

遍历顺序:严格按照插入顺序输出 → AA → 456 → Customer(刘,1001) → 123 → HSP

重复元素 456 只会保留一份,符合 Set 集合 “不允许重复” 的特性。

4.元素特性:不允许添加重复元素。

点击图片可查看完整电子表格

Map接口(存储key-value键值对),与Collection接口并列

Map接口和常用方法(Map接口实现类——HashMap)

Map 接口实现类的特点,使用实现类 HashMap举例

1.Map 与 Collection 并列存在。用于保存具有映射关系的数据:Key-Value (双列元素)

2.Map 中的 key 和 value 可以是任何引用类型的数据,会封装到 HashMap$Node 对象中

3.Map 中的 key 不允许重复,原因和 HashSet 一样,前面分析过源码。

4.Map 中的 value 可以重复

5.Map 的 key 可以为 null, value 也可以为 null ,注意 key 为 null, 只能有一个,value 为 null , 可以多个。

6.常用 String 类作为 Map 的 key

7.key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到对应的 value

Java                  Map map=new Map();

TypeScript                  import java.util.HashMap;                  import java.util.Map;                  /**                     * 演示JDK8中HashMap的核心特点                     * 对应Map接口实现类的核心特性                     */                  public class HashMapFeaturesDemo {                  public static void main(String[] args) {                  // 创建HashMap对象,Key为String类型,Value为Integer类型                  Map<String, Integer> hashMap = new HashMap<>();                  //常用String类作为Map的key// 1. 向Map中添加键值对(Key-Value映射关系)hashMap.put("张三", 20);                  hashMap.put("李四", 22);                  hashMap.put("王五", 20); // value可以重复hashMap.put("赵六", null); // value可以为null                  hashMap.put(null, 30); // key可以为null                  hashMap.put(null, 35); // key为null只能有一个(后面的会覆盖前面的)hashMap.put("孙七", null); // 可以有多个value为null                  //hashMap.put("张三", 100); //当key值相等时,就等价于替换,将前面的20改为100// 打印整个HashMap,查看结果                  System.out.println("1. 完整的HashMap内容:" + hashMap);                  // 输出:{null=35, 张三=20, 李四=22, 王五=20, 赵六=null, 孙七=null}                  // 2. 验证key不允许重复(重复添加会覆盖原有value)hashMap.put("张三", 25); // 重复的key,覆盖原有value                  System.out.println("2. 重复添加key'张三'后的结果:" + hashMap.get("张三"));                  // 输出:25(原20被覆盖)                  // 3. 验证value可以重复                  System.out.println("3. 验证value可以重复:");                  System.out.println("'张三'的value:" + hashMap.get("张三")); // 20                  System.out.println("'李四'的value:" + hashMap.get("李四")); // 22                  System.out.println("'王五'的value:" + hashMap.get("王五")); // 20                  // 可以看到value=20出现了多次// 4. 验证key为null只能有一个                  System.out.println("4. key为null的value值:" + hashMap.get(null));                  // 输出:35(最后一次添加的null key对应的value)                  // 5. 验证value为null可以有多个                  System.out.println("5. 多个value为null的验证:");                  System.out.println("'赵六'的value:" + hashMap.get("赵六")); // null                  System.out.println("'孙七'的value:" + hashMap.get("孙七")); // null                  // 6. 验证key和value的单向一对一关系(通过key总能找到唯一的value)                  String targetKey = "李四";                  Integer targetValue = hashMap.get(targetKey);                  System.out.println("6. 通过key'" + targetKey + "'找到的value:" + targetValue);                  // 输出:22(唯一对应)                  // 7. 常用操作:遍历Map                  System.out.println("\n7. 遍历HashMap的所有键值对:");                  for (Map.Entryentry : hashMap.entrySet()) {          System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());          }          }          }

8.

Entry 映射关系每一对 key-value 本质上是一个 Map.Entry 对象,HashMap 中用内部类 Node 实现了 Entry 接口。

HashMap$Node 与 Entry 的关系

HashMap$Node 是 HashMap 的静态内部类,它实现了 Map.Entry 接口。

因此,一个 Node 对象就代表了一个完整的 key-value 映射,所以很多资料会直接说 “一对 k-v 就是一个 Entry”(不严谨)。

node内部代码简化:

Java                  static class Nodeimplements Map.Entry{           final int hash;           final K key;           V value;           Nodenext; // 用于链表解决哈希冲突            }

代码演示(为了方便程序员遍历,会创建EntrySet集合,该集合存放的元素的类型Entry对象,而一个Entry对象就有key-value对象,提供getKey()和getValue方法获取):

TypeScript                  import java.util.HashMap;                  import java.util.Map;                  public class MapEntryDemo {                  public static void main(String[] args) {                  Mapmap = new HashMap<>();          map.put("Java", 100);          map.put("Python", 90);          Set set=map.entrySet();          sout(set.getClass());//输出HashMap$EntrySet集合(即HashMap中的EntrySet集合 )          //entrySet中定义的类型是Map.Entry,但实际上存放的还是HashMap$Node(即HashMap中的Node类)          //因为static class Nodeimplements Map.Entry类,方便遍历(多态:A类实现B接口类,则A类对象实例(Node)可以赋值给B类的接口类型(Entry))//Map.Entry提供K:getKey();V: getVakue()方法                   // 遍历 Entry 集合,本质上就是遍历 Node,为了遍历方便而创建EntrySet集合for (Map.Entryentry: map.entrySet()) {                  System.out.println("key: " + entry.getKey() + ", value: " + entry.getValue());                  }                  }                  }

Map接口常用方法

点击图片可查看完整电子表格

代码示例:

Go                  import java.util.HashMap;                  import java.util.Map;                  public class MapMethod {                  public static void main(String[] args) {                  Mapmap = new HashMap<>();          // 1. put:添加元素          map.put("Java", 100);          map.put("Python", 90);          map.put("Java", 95); // 覆盖旧值          // 2. size:获取元素个数          System.out.println("元素个数:" + map.size()); // 输出 2          // 3. isEmpty:判断是否为空          System.out.println("是否为空:" + map.isEmpty()); // 输出 false          // 4. get:根据 key 获取 value          System.out.println("Java 的分数:" + map.get("Java")); // 输出 95          // 5. containsKey:判断 key 是否存在          System.out.println("是否包含 C++:" + map.containsKey("C++")); // 输出 false          // 6. remove:根据 key 删除元素          Integer removed = map.remove("Python");          System.out.println("被删除的 value:" + removed); // 输出 90          // 7. clear:清空所有元素          map.clear();          System.out.println("清空后元素个数:" + map.size()); // 输出 0          }          }

Map六大遍历方法

遍历方式分类

第一组:通过 keySet() 获取所有 key,再遍历 key 得到 value。

第二组:通过 values() 直接获取所有 value,仅遍历值。

第三组:通过 entrySet() 获取键值对 Entry 对象,一次遍历得到 key 和 value,效率最高(推荐使用)。

代码示例:

Java                  import java.util.Collection;                  import java.util.HashMap;                  import java.util.Iterator;                  import java.util.Map;                  import java.util.Set;                  @SuppressWarnings({"all"})                  public class MapFor {                  public static void main(String[] args) {                  Map map = new HashMap();                  map.put("邓超", "孙俪");                  map.put("王宝强", "马蓉");                  map.put("宋喆", "马蓉");                  map.put("刘令博", null);                  map.put(null, "刘亦菲");                  map.put("鹿晗", "关晓彤");                  // 第一组:先取出所有的Key,通过Key取出对应的Value                  Set keySet = map.keySet();                  // (1) 增强for                  System.out.println("-----第一种方式-----");                  for (Object key : keySet) {                  System.out.println(key + "-" + map.get(key));                  }                  // (2) 迭代器                  System.out.println("-----第二种方式-----");                  Iterator iterator = keySet.iterator();                  while (iterator.hasNext()) {                  Object key = iterator.next();                  System.out.println(key + "-" + map.get(key));                  }                       // 第二组:把所有的values取出                  Collection values = map.values();                  // (1) 增强for                  System.out.println("---取出所有的value 增强for---");                  for (Object value : values) {                  System.out.println(value);                  }               // (2) 迭代器                  System.out.println("---取出所有的value 迭代器---");                  Iterator iterator2 = values.iterator();                  while (iterator2.hasNext()) {                  Object value = iterator2.next();                  System.out.println(value);                  }                  // 第三组:通过EntrySet来获取k-v                         Set entrySet = map.entrySet();                  // (1) 增强for                  System.out.println("---使用EntrySet的for增强(第3种)---");                  for (Object entry : entrySet) {                  // 将entry转成Map.Entry                  Map.Entry m = (Map.Entry) entry;                  System.out.println(m.getKey() + "-" + m.getValue());                  }                         // (2) 迭代器                  System.out.println("---使用EntrySet的迭代器(第4种)---");                  Iterator iterator3 = entrySet.iterator();                  while (iterator3.hasNext()) {                  Object entry = iterator3.next();                  // 向下转型 Map.Entry                  Map.Entry m = (Map.Entry) entry;                  System.out.println(m.getKey() + "-" + m.getValue());                  }                  }                  }

泛型优化提示:实际开发中建议使用泛型(如 Map),避免强制类型转换,代码更安全简洁:

JavaScript                  Mapmap = new HashMap<>();          // ...          for (Map.Entryentry : map.entrySet()) {           System.out.println(entry.getKey() + "-" + entry.getValue());           }

练习

题目:

代码:

Java                  import java.util.HashMap;                  import java.util.Iterator;                  import java.util.Map;                  import java.util.Set;                  // 员工类:封装属性,提供getter/setter和toString                  class Emp {                  private String name;                  private double sal;                  private int id;                  // 构造器                  public Emp(String name, double sal, int id) {                  this.name = name;                  this.sal = sal;                  this.id = id;                  }                  // getter/setter 封装方法,实现数据封装与安全访问public String getName() {                  return name;                  }                  public void setName(String name) {                  this.name = name;                  }                  public double getSal() {                  return sal;                  }                  public void setSal(double sal) {                  this.sal = sal;                  }                  public int getId() {                  return id;                  }                  public void setId(int id) {                  this.id = id;                  }                  // 重写toString,方便打印对象信息                  @Override                  public String toString() {                  return "Emp{" +                  "name='" + name + '\'' +                  ", sal=" + sal +                  ", id=" + id +                  '}';                  }                  }                  // 主类:Map练习                  @SuppressWarnings({"all"})                  public class MapExercise {                  public static void main(String[] args) {                  Map hashMap = new HashMap();                  // 添加员工对象(键:员工id,值:Emp对象)                  hashMap.put(1, new Emp("jack", 300000, 1));                  hashMap.put(2, new Emp("tom", 1000, 2));                  hashMap.put(3, new Emp("milan", 12000, 3));                  // 遍历方式1:keySet + 增强for                  //方式 1通过 keySet() 获取所有键,遍历键后用 get(key)                   //获取对应 Emp 对象,再筛选工资。                  System.out.println("=====第一种遍历方式(keySet+增强for)=====");                  Set keySet = hashMap.keySet();                  for (Object key : keySet) {                  Emp emp = (Emp) hashMap.get(key);                  // 筛选工资>18000的员工                  if (emp.getSal() > 18000) {                  System.out.println(emp);                  }                  }                  // 遍历方式2:entrySet + 迭代器                  //方式 2:通过 entrySet() 获取键值对 Entry 集合,                  //用迭代器遍历,直接从 Entry 中取出 value(即 Emp 对象),效率更高(推荐)。                  System.out.println("=====第二种遍历方式(entrySet+迭代器)=====");                  Set entrySet = hashMap.entrySet();                  Iterator iterator = entrySet.iterator();                  while (iterator.hasNext()) {                  Map.Entry entry = (Map.Entry) iterator.next();                  Emp emp = (Emp) entry.getValue();                  // 筛选工资>18000的员工                  if (emp.getSal() > 18000) {                  System.out.println(emp);                  }                  }                  }                  }

运行结果:

Java                  =====第一种遍历方式(keySet+增强for)=====                  Emp{name='jack', sal=300000.0, id=1}                  =====第二种遍历方式(entrySet+迭代器)=====                  Emp{name='jack', sal=300000.0, id=1}

实际开发中建议使用泛型,避免强制类型转换,代码更安全:

Java                  MaphashMap = new HashMap<>();          // ...          for (Integer key : hashMap.keySet()) {          Emp emp = hashMap.get(key);          }          // 或          for (Map.Entryentry : hashMap.entrySet()) {           Emp emp = entry.getValue();           }

HashMap小结

1.Map 接口常用实现类

HashMapHashtableProperties

1.3.1.1 HashMap 地位

是 Map 接口中使用频率最高 的实现类

1.3.1.2 数据存储方式

以 key-value 键值对 形式存储,底层通过 EntryHashMap$Node)对象封装每一对 k-v

1.3.1.3 key 与 value 特性

key不可重复,允许为 null(最多 1 个 null key)

value可重复,允许为 null多个 null value 均可)

1.3.1.4 重复 key 处理

若添加已存在的 key,不会新增,而是覆盖原有的 value,等价于 “修改操作”(key 保持不变,仅替换 value)

1.3.1.5 顺序性

与 HashSet 一致,不保证存储 / 遍历顺序,因为底层基于 hash 表的方式来存储的(hashMap底层:数组+链表+红黑树

1.3.1.6 线程安全

未实现同步(synchronized),因此是 线程不安全 的,多线程环境下需手动处理同步或使用 ConcurrentHashMap

HashMap底层原理和代码剖析

该方面靠理解,可观看原视频536~538

结论:

精简记忆版

1.结构:Node 数组 table,初始为 null

2.加载因子:默认 0.75,首次扩容后容量 16,临界值 12

3.添加:哈希定位 → 冲突判断 → 链表 / 红黑树处理 → 覆盖 / 追加

4.扩容:2 倍扩容,临界值同步 2 倍

5.树化:链表长度 ≥ 8 且数组容量 ≥ 64 → 转红黑树

Map接口实现类——HashTable

基本介绍

存储结构

存放元素为 键值对(K-V,实现 Map 接口,与 HashMap结构一致。

1.3.1.7 Key 与 Value 的限制

键(key)不能为 null

值(value)不能为 null

违反任一限制将直接抛出 NullPointerException 空指针异常

Java                  import java.util.Hashtable;                  @SuppressWarnings({"all"})                  public class HashTableExercise {                  public static void main(String[] args) {                  Hashtable table = new Hashtable();//ok                  table.put("john", 100); //ok                  //table.put(null, 100); //异常 NullPointerException                  //table.put("john", null);//异常 NullPointerException                  table.put("lucy", 100);//ok                  table.put("lic", 100);//ok                  table.put("lic", 88);//替换                  System.out.println(table);                  }                  }

1.3.1.8 使用方式

使用方法 基本与 HashMap 一致,常用方法如 put()get()remove() 等用法相同。

1.3.1.9 线程安全性

线程安全:方法采用 synchronized 同步修饰,多线程操作时无需额外同步控制。

线程不安全:与之对比,HashMap 未实现同步,多线程环境下可能出现数据异常。

Map接口实现类——Properties

常用于读取配置文件,如何读取配置文件可前往:

为什么要有配置文件这种东西呢?

因为类似数据库的JDBC就将数据库连接代码写死了,将用户账号和密码等信息写死在了代码里边,如果需要修改就得修改代码,这就意味着需要重新测试运行打包;

https://www.cnblogs.com/xudong-bupt/p/3758136.html学习(韩顺平的随笔学习笔记,产自博客园,一个类似CSDN的程序员网站

基本介绍

继承与实现

继承自 Hashtable 类,同时实现了 Map 接口,本质是一个键值对存储结构。

数据存储形式与 HashMap/Hashtable 一致,为K-V 键值对

1.3.2 使用特点

基础使用方式与 Hashtable 类似,线程安全(继承了 synchronized 方法)

允许 key 或 value 为 null(继承自 Hashtable 的特性)。

1.3.3 核心特殊功能

支持从 .properties 配置文件中加载数据到 Properties 对象。

可对加载后的配置数据进行读取修改操作,是 Java 中处理配置文件的标准类。

1.3.4 工程应用说明

.properties 文件是工作中常用的配置文件格式如数据库连接、系统参数配置)。

该知识点在 Java IO 流章节,是后端开发的高频实用技能。

1.3.5 拓展学习链接

https://www.cnblogs.com/xudong-bupt/p/3758136.html

代码示例:

Java                  import java.util.Properties;                  public class Properties_ {                  public static void main(String[] args) {                  // 1. Properties 继承 Hashtable// 2. 可以通过 k-v 存放数据,当然 key 和 value 不能为 null                  // 增加                  Properties properties = new Properties();                  // properties.put(null, "abc"); // 抛出 空指针异常                  // properties.put("abc", null); // 抛出 空指针异常                  properties.put("john", 100); // k-v                  properties.put("lucy", 100);                  properties.put("lic", 100);                  properties.put("lic", 88); // 如果有相同的 key,value 被替换                  // 打印所有键值对                  System.out.println("properties=" + properties);                  //(Properties 不保证遍历顺序,输出顺序可能与插入顺序不同)                  // 通过 k 获取对应值                  System.out.println(properties.get("lic")); // 88                  }                  }

实际开发中如何选择集合实现类

核心选择口诀(底层代码解释请观看视频542-544,靠理解)

1.先分类型:单列用 Collection,双列用 Map

2.单列再分

要重复 → 用 List:增删多用 LinkedList,改查多用 ArrayList

不要重复 → 用 Set:要无序用 HashSet,要排序用 TreeSet(继承Set接口,相当于简介继承了collection接口,最大特点是可以排序),要顺序不变用 LinkedHashSet

TypeScript                  import java.util.Comparator;                  import java.util.TreeSet;                  public class TreeSet_java {                  public static void main(String[] args) {                  // 1. 当我们使用无参构造器,创建TreeSet时,仍然是无序的(按自然排序)// 2. 我们希望添加的元素,按照字符串大小来排序(降序)// 3. 使用TreeSet提供的构造器,传入一个比较器(匿名内部类)并指定排序规则                  // 方式1:无参构造器(自然排序,即无序)                  // TreeSet treeSet = new TreeSet();// 方式2:带比较器的构造器(自定义排序)                  TreeSet treeSet = new TreeSet(new Comparator() {                  @Override                  public int compare(Object o1, Object o2) {                  // 调用String的compareTo方法进行字符串大小比较                  // o2.compareTo(o1) → 降序排序;o1.compareTo(o2) → 升序排序                  return ((String) o2).compareTo((String) o1);                  }                  });                  // 添加数据                  treeSet.add("jack");                  treeSet.add("tom");                  treeSet.add("sp");                  treeSet.add("a");                  // 打印结果:treeSet=[tom, sp, jack, a]                  System.out.println("treeSet=" + treeSet);                  }                  }                  

3.双列再分

键无序 → HashMap

键要排序 → TreeMap(底层是红黑树)

TreeMap:自然排序版(底层是红黑树,会默认对Key排序,String默认a-z)

Java                  import java.util.TreeMap;                  public class TreeMapDemo {                  public static void main(String[] args) {                  // 使用默认的构造器,创建TreeMap(按键的自然排序)                  TreeMap treeMap = new TreeMap();treeMap.put("jack", "杰克");                  treeMap.put("tom", "汤姆");treeMap.put("kristina", "克瑞斯提诺");                  treeMap.put("smith", "斯密斯");                  // 打印时,会按照 key (String) 的字典序自动排序                  System.out.println("treeMap=" + treeMap);                  //treeMap={jack=杰克, kristina=克瑞斯提诺, smith=斯密斯, tom=汤姆}                  }                  }

TreeMap自定义排序版本:

TypeScript                  import java.util.Comparator;                  import java.util.TreeMap;                  public class TreeMapCustom {                  public static void main(String[] args) {                  // 这里使用带比较器的构造器                  TreeMap treeMap = new TreeMap(new Comparator() {                  @Override                  public int compare(Object o1, Object o2) {                  // 按照传入的 k(String) 的大小进行排序                  // 调用 String 的 compareTo 方法实现字典序比较                  return ((String) o1).compareTo((String) o2);                  }                  });                  // 添加数据                  treeMap.put("jack", "杰克");                  treeMap.put("tom", "汤姆");                  treeMap.put("kristina", "克瑞斯提诺");                  treeMap.put("smith", "斯密斯");                  // 打印结果                  System.out.println("treeMap=" + treeMap);                  }                  }

要保持插入顺序 → LinkedHashMap

读配置文件 → Properties

Collections工具类(545~546)

这里的Collections带s,和Collection接口不是一回事,给Java提供的集合工具类(服务于Collection接口(List/Set)和Map接口对象)

1.所有方法均为 static 静态方法,无需创建对象,直接通过类名调用,可对集合元素进行排序、查询、修改等操作。

点击图片可查看完整电子表格

Java                  import java.util.ArrayList;                  import java.util.Collections;                  import java.util.Comparator;                  import java.util.List;                  public class Collections_ {                  public static void main(String[] args) {                  Listlist = new ArrayList<>();          list.add(3);          list.add(1);          list.add(2);          list.add(5);          list.add(4);          // 1. reverse:反转Collections.reverse(list);System.out.println("反转后:" + list); // [4,5,2,1,3]                  // 2. shuffle:随机打乱Collections.shuffle(list);System.out.println("随机打乱后:" + list); // 每次结果不同                  // 3. sort:自然升序                  Collections.sort(list);System.out.println("自然升序后:" + list); // [1,2,3,4,5]                  // 4. sort:自定义降序Collections.sort(list, new Comparator(){                  @Override                  public int compare(Integer o1, Integer o2) {                  return o2 - o1; // 降序                  }                  });                  System.out.println("自定义降序后:" + list); // [5,4,3,2,1]                  // 5. swap:交换索引 0 和 2 的元素                  Collections.swap(list, 0, 2);                  System.out.println("交换后:" + list); // [3,4,5,2,1]                  }                  }

记忆要点

Collections 是工具类,方法全是 static

排序类方法主要针对 List,Set/Map需先转成 List 再操作

sort() 有两个重载:自然排序 vs 自定义比较器排序。

查找,替换

示例代码:

Java                  import java.util.ArrayList;                  import java.util.Collections;                  import java.util.Comparator;                  import java.util.List;                  @SuppressWarnings({"all"})                  public class Collections_ {                  public static void main(String[] args) {                  // 1. 创建 ArrayList 集合,用于测试                  List list = new ArrayList();                  list.add("tom");list.add("smith");list.add("king");list.add("milan");list.add("tom"); // 重复元素,用于测试 frequency// 2. reverse(List): 反转 List 中元素的顺序                  Collections.reverse(list);System.out.println("反转后 list=" + list);                  // 3. shuffle(List): 对 List 集合元素进行随机排序// Collections.shuffle(list);                  // System.out.println("随机打乱后 list=" + list);                  // 4. sort(List): 按元素自然顺序升序排序(String 字典序)                  Collections.sort(list);System.out.println("自然排序后 list=" + list);                  // 5. sort(List, Comparator): 按字符串长度升序自定义排序Collections.sort(list, new Comparator() {                  @Override                  public int compare(Object o1, Object o2) {                  // 按字符串长度比较:长度小的在前                  return ((String) o1).length() - ((String) o2).length();                  }                  });                  System.out.println("字符串长度大小排序后 list=" + list);                  // 6. swap(List, int, int): 交换指定索引的元素Collections.swap(list, 0, 1);System.out.println("交换后的情况");                  System.out.println("list=" + list);                  // 7. max(Collection): 自然顺序最大值Object maxObject = Collections.max(list);System.out.println("自然顺序最大元素=" + maxObject);                  // 8. max(Collection, Comparator): 按字符串长度找最大值                  Object maxLengthObj = Collections.max(list, new Comparator() {                  @Override                  public int compare(Object o1, Object o2) {                  return ((String) o1).length() - ((String) o2).length();                  }                  });                  System.out.println("长度最大的元素=" + maxLengthObj);                  // 9. min(Collection) / min(Collection, Comparator): 参考 max 方法// 用法与 max 一致,此处省略                  // 10. frequency(Collection, Object):统计元素出现次数int tomCount = Collections.frequency(list, "tom");System.out.println("tom出现的次数=" + tomCount);                  // 11. copy(List dest, List src): 复制集合                  // 注意:dest 必须先初始化足够的容量!                  ArrayList dest = new ArrayList();                  // 先填充占位元素,保证容量与 list 一致                  for (int i = 0; i < list.size(); i++) {                  dest.add("");                  }                  Collections.copy(dest, list);System.out.println("复制后的 dest=" + dest);                  // 12. replaceAll(List list, Object oldVal, Object newVal): 批量替换Collections.replaceAll(list, "tom", "汤姆");System.out.println("list替换后=" + list);                  }                  }

Java                  反转后 list=[tom, milan, king, smith, tom]                  自然排序后 list=[king, milan, smith, tom, tom]                  字符串长度大小排序后 list=[milan, smith, king, tom, tom]                  交换后的情况list=[smith, milan, king, tom, tom]                  自然顺序最大元素=tom                  长度最大的元素=smith                  tom出现的次数=2                  复制后的 dest=[smith, milan, king, tom, tom]                  list替换后=[smith, milan, king, 汤姆, 汤姆]

记忆要点

max/min:支持自然排序和自定义比较器,可作用于所有 Collection

frequency:快速统计元素出现频率,适合去重、计数场景。

copy目标列表必须先扩容,否则会报错,这是高频易错点。

replaceAll:批量替换 List 中所有匹配的旧值,返回是否发生替换

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-03-27 03:47:17 HTTP/2.0 GET : https://67808.cn/a/474557.html
  2. 运行时间 : 0.158727s [ 吞吐率:6.30req/s ] 内存消耗:4,883.48kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=f09236442d13845e6d05934151ca15b0
  1. /yingpanguazai/ssd/ssd1/www/no.67808.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/no.67808.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/no.67808.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/no.67808.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/no.67808.cn/runtime/temp/6df755f970a38e704c5414acbc6e8bcd.php ( 12.06 KB )
  140. /yingpanguazai/ssd/ssd1/www/no.67808.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000985s ] mysql:host=127.0.0.1;port=3306;dbname=no_67808;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001565s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000620s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000571s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001085s ]
  6. SELECT * FROM `set` [ RunTime:0.000491s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001135s ]
  8. SELECT * FROM `article` WHERE `id` = 474557 LIMIT 1 [ RunTime:0.002383s ]
  9. UPDATE `article` SET `lasttime` = 1774554437 WHERE `id` = 474557 [ RunTime:0.011681s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 65 LIMIT 1 [ RunTime:0.000559s ]
  11. SELECT * FROM `article` WHERE `id` < 474557 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000947s ]
  12. SELECT * FROM `article` WHERE `id` > 474557 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000897s ]
  13. SELECT * FROM `article` WHERE `id` < 474557 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.003889s ]
  14. SELECT * FROM `article` WHERE `id` < 474557 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.001976s ]
  15. SELECT * FROM `article` WHERE `id` < 474557 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.002494s ]
0.161558s