Java集合之综合论述

执键写春秋
• 阅读 1476

1.Java集合

1.1 集合应用场景

  1. 无法预测存储数据的数量的情况下,
  2. 同时存储一对一关系的数据
  3. 需要进行数据的增删
  4. 数据重复问题

    1.2 集合框架的体系结构

    集合框架分为两类,一是Collection,用于存储类的对象。二是Map,以键值对的形式存储信息。
  • Collection主要有三个子接口,List(序列),Queue(队列),Set(集)。其中List和Queue要求存入数据有序且允许重复,Set中存入数据要求无序并且不能重复。List接口下有个常用实现类ArrayList,可以看为一个长度动态增长的数组。Queue接口下有常用实现类LinkedList,同时也实现了List接口,表示的是列表的内容。Set下有实现类HashSet表示哈希集。
  • Map主要实现类是HashMap(哈希表),存储以键值对形式存放的数据。 Java集合之综合论述

    1.3 集合与数组的区别

  1. 数组的长度是固定的,集合的长度可以动态扩展;
  2. 数组只能存储相同数据类型的数据,而集合可以存储不同数据类型的数据;
  3. 数组可以存储基本数据类型数据,也可以是引用类型,而集合只能是引用类型;
  4. 数组适用于数据长度固定的情况,并且主要进行查询操作。

    1.4 集合中接口和类的特点

    1.4.1 Collection

    主要用于存储类的对象,Collection下有三个子接口,分别是List、Queue和Set,List和Queue中可以存储有序且重复的数据,Set中存储的数据是无序且不允许重复。

1、List接口的主要实现类包括ArrayList和LinkedList,LinkedList同时实现了Queue接口。

  • ArrayList的底层实现是数组,因此在内存中是连续存储的。查询速度快,但增加和删除速度慢。
  • LinkedList底层是基于双向链表的,增加和删除速度快,查询速度慢。

2、Set接口的主要实现类有HashSet和TreeSet

  • HashSet是基于哈希表实现的,数据是无序的,HashSet元素可以是null,但只能有一个null。
  • TreeSet是基于二叉树实现的,可以实现数据的自动排序,确保集合元素处于非排序状态,不允许放入空值。
  • HashSet的性能优于TreeSet,一般情况下建议使用HashSet,如果需要使用排序功能建议使用TreeSet。

    1.4.2 Map

    主要用于存储键值对的数据,Map的主要实现类包括HashMap和TreeMap,其中HashMap基于哈希表实现,TreeMap基于红黑树实现。 1. HashMap适用于在Map中插入、删除和定位元素。 2. TreeMap适用于按自然顺序或自定义顺序对建值进行遍历。 3. HashMap比TreeMap性能好,所以HashMap使用更多一些,如果需要对数据进行排序可以使用TreeMap。

    1.5 集合-List

  • List是元素有序并且可以重读的集合,称为序列
  • List可以精确控制每一个元素的插入位置,或者删除某个位置的元素
  • List两个主要实现类ArrayList和LinkedList,两个接口方法基本相同,ArrayList使用更多
  • ArrayList是长度动态变化的数组,底层由数组实现。由于与数组一样是连续存储的,所以在列表尾部插入或者删除数据效率非常高,但是中间插入或者删除数据需要进行大量数组复制,效率比较低。所以ArrayList更适合查找和更新元素。
  • ArrayList元素可以为null。

    1.5.1 使用ArrayList存储数据并输出

    public class Demo {
      public static void main(String[] args) {
          // 用ArrayList存储编程语言并输出
          List list = new ArrayList();
          list.add("JAVA");
          list.add("Hello");
          list.add("World");
          // 输出列表中的元素个数
          System.out.println("列表中的元素个数为:" + list.size());
          // 遍历输出所有编程语言
          System.out.println("***********************************");
          for (int i = 0; i < list.size(); i++) {
              System.out.print(list.get(i) + ",");
          }
          // 移除列表中的Java;
          System.out.println();
          list.remove(0);//数据存储位置
          //list.remove("JAVA");// 直接输入要移除的数
          System.out.println("***********************************");
          System.out.println("判断此时是否包含JAVA,如果包含则输出true,否则false:"+list.contains("JAVA"));
          System.out.println("移除Java以后的列表元素为:");
          for (int i = 0; i < list.size(); i++) {
              System.out.print(list.get(i) + ",");
          }
      }
    }
    输出:
    列表中的元素个数为:3

JAVA,Hello,World,


判断此时是否包含JAVA,如果包含则输出true,否则false:false 移除Java以后的列表元素为: Hello,World,

### 1.5.2 案例实现(公告管理)
**需求:**
➩ 公告的添加和显示
➩ 在指定位置处插入公告
➩ 删除公告
➩ 修改公告
- **第一步 公告类的定义**

【属性:公告ID、公告标题、公告创建人、公告创建时间】

package person.xsc.practice; import java.util.Date; public class Notice { private int id; // 公告ID private String title; //公告标题 private String creator; // 公告创建人 private Date createTime;//公告创建时间 public Notice() {

}
public Notice(int id, String title, String creator, Date createTime) {
    super();
    this.id = id;
    this.title = title;
    this.creator = creator;
    this.createTime = createTime;
}
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getTitle() {
    return title;
}
public void setTitle(String title) {
    this.title = title;
}
public String getCreator() {
    return creator;
}
public void setCreator(String creator) {
    this.creator = creator;
}
public Date getCreateTime() {
    return createTime;
}
public void setCreateTime(Date createTime) {
    this.createTime = createTime;
}
@Override
public String toString() {
    return "Notice [id=" + id + ", title=" + title + ", creator=" + creator + ", createTime=" + createTime + "]";
}

}

- **第二步,测试类的定义**

package person.xsc.practice; import java.util.ArrayList; import java.util.Date; public class TestNotice { public static void main(String[] args) { // TODO Auto-generated method stub // 创建公告对象 Notice notice1 = new Notice(1, "欢迎来到我的世界——编程世界", "执键写春秋", new Date()); Notice notice2 = new Notice(2, "你好,世界", "执键写春秋", new Date()); Notice notice3 = new Notice(3, "你好,程序员", "执键写春秋", new Date()); Notice notice4 = new Notice(4, "开始写代码", "执键写春秋", new Date()); // 添加公告 ArrayList noticeList = new ArrayList(); noticeList.add(notice1); noticeList.add(notice2); noticeList.add(notice3); noticeList.add(notice4); // 显示公告内容 System.out.println("公告内容为: "); for (Object object : noticeList) { System.out.println(((Notice) object).getId() + " " + ((Notice) object).getTitle() + " " + ((Notice) object).getCreator() + " " + ((Notice) object).getCreateTime()); } // 在第一条公告后面添加一条新公告 Notice notice5 = new Notice(5, "抓紧学习", "执键写春秋", new Date()); noticeList.add(1, notice5); System.out.println("添加后的公告内容为: "); for (Object object : noticeList) { // 这里标题使用跟之前有所不同 System.out.println(((Notice) object).getId() + ": " + ((Notice) object).getTitle()); } // 删除按时完成作业的公告 noticeList.remove(2); System.out.println("删除后的公告内容为: "); for (Object object : noticeList) { // 这里标题使用跟之前有所不同 System.out.println(((Notice) object).getId() + ": " + ((Notice) object).getTitle()); } // 1. 修改公告的title值 notice4.setTitle("不要你写代码了"); System.out.println("修改后公告内容为: "); for (Object object : noticeList) { // 这里标题使用跟之前有所不同 System.out.println(((Notice) object).getId() + ": " + ((Notice) object).getTitle()); } } } 输出: 公告内容为: 1 欢迎来到我的世界——编程世界 执键写春秋 Tue May 11 17:13:02 CST 2021 2 你好,世界 执键写春秋 Tue May 11 17:13:02 CST 2021 3 你好,程序员 执键写春秋 Tue May 11 17:13:02 CST 2021 4 开始写代码 执键写春秋 Tue May 11 17:13:02 CST 2021 添加后的公告内容为: 1: 欢迎来到我的世界——编程世界 5: 抓紧学习 2: 你好,世界 3: 你好,程序员 4: 开始写代码 删除后的公告内容为: 1: 欢迎来到我的世界——编程世界 5: 抓紧学习 3: 你好,程序员 4: 开始写代码 修改后公告内容为: 1: 欢迎来到我的世界——编程世界 5: 抓紧学习 3: 你好,程序员 4: 不要你写代码了

## 1.6 集合-Set
【提示:Set是接口,不能创建对象,】
Set:元素无需并且不可以重复的集合,被称为集。HashSet是Set一个重要的实现类。
- HashSet是Set一个重要的实现类,称为哈希集;
- HashSet中元素无序并且不可以重复;
- HashSet只允许有一个null元素;
- 具有良好的存取和查找性能;
- HashSet的底层实现其实是HashMap;
- HashSet没有get方法。
### 1.6.1 使用HashSet存储数据并输出

package person.xsc.practice; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class TestNotice { public static void main(String[] args) { Set set=new HashSet(); //向集合中添加元素 set.add("H"); set.add("e"); set.add("ll"); set.add("o"); //显示集合的内容 System.out.println("集合中的元素为:"); Iterator it=set.iterator(); //遍历迭代器并输出元素 while(it.hasNext()) { System.out.print(it.next()+" "); } System.out.println(); //在集合中插入一个重复的单词 set.add("o"); //遍历迭代器并输出元素 System.out.println("**"); System.out.println("插入重复元素后的输出结果为"); it=set.iterator(); while(it.hasNext()) { System.out.print(it.next()+" "); } //插入失败,但是不会失败 } } 输出: 集合中的元素为: ll e H o


插入重复元素后的输出结果为 ll e H o

### 1.6.2 迭代器(iterator)
在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了一个接口java.util.Iterator。Iterator接口也是Java集合中的一员,但它与Collection、Map接口有所不同,Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象也被称为迭代器。
- hasNext()方法检测集合中是否还有下一关元素,它的返回值是boolean类型。**(当hasNext()方法的返回值为false时,表示集合中的元素已经遍历完毕。)**
- next()方法返回集合中的下一个元素,返回Object类型的对象。
### 1.6.3 案例实现(宠物猫管理)
**需求**
➩添加和显示宠物猫信息
➩查找某只宠物猫的信息并输出
➩修改宠物猫的信息
➩删除宠物猫信息
- **第一步 猫猫类的定义**

package person.xsc.practice; public class Cat { private String name; private int month; private String kinds; public Cat() { } public Cat(String name,int month,String kinds) { this.name=name; this.month=month; this.kinds=kinds; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public String getKinds() { return kinds; } public void setKinds(String kinds) { this.kinds = kinds; } @Override public String toString() { return "Cat [name=" + name + ", month=" + month + ", kinds=" + kinds + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((kinds == null) ? 0 : kinds.hashCode()); result = prime * result + month; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { //先判断对象是否相等,相等则返回true,不用继续比较属性了 if(this==obj) return true; //判断obj是否是Cat类的对象 if(obj.getClass()==Cat.class){ //如果是,则强制转换成cat类型,然后比较各个属性是否相等 Cat cat=(Cat)obj; return cat.getName().equals(name)&&(cat.getMonth()==month)&&(cat.getKinds().equals(kinds));

    }
    return false;
}

}

- **第二步,测试类的定义**

package person.xsc.practice; import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class TestCat { public static void main(String[] args) { // TODO Auto-generated method stub //定义宠物猫对象 Cat huahua=new Cat("小花",12,"英国短毛猫"); Cat fanfan=new Cat("小凡",3,"中华田园猫"); //将宠物猫对象放入HashSet中 Set set=new HashSet(); set.add(huahua); set.add(fanfan); //显示宠物猫信息 Iterator it=set.iterator(); while(it.hasNext()){ System.out.println(it.next()); } //再添加一个与花花属性一样的猫 Cat huahua01=new Cat("小花",12,"英国短毛猫"); set.add(huahua01); System.out.println("**"); System.out.println("添加重复数据后的宠物猫信息:"); it= set.iterator(); while(it.hasNext()){ System.out.println(it.next()); } //在集合中查找花花的信息并输出 System.out.println("****"); //方案1:使用对象查找 if(set.contains(huahua)){ System.out.println("小花找到了!"); System.out.println(huahua); } else{ System.out.println("小花没找到"); } //方案2:使用名字查找 System.out.println("****"); it= set.iterator(); boolean flag = false; Cat c = null; while (it.hasNext()) { c = (Cat) it.next(); if (c.getName().equals("小花花")) { flag = true;// 找到了 break; } } if (flag) { System.out.println("小花花找到了"); System.out.println(c); } else { System.out.println("小花花没找到"); } //删除huahua对象 System.out.println("****"); //方案一:直接通过对象名删除 set.remove(huahua); it= set.iterator(); while (it.hasNext()) { System.out.println(it.next()); } //方案二:可以尝试通过别的方法删除 } }

输出: Cat [name=小凡, month=3, kinds=中华田园猫] Cat [name=小花, month=12, kinds=英国短毛猫]


添加重复数据后的宠物猫信息: Cat [name=小凡, month=3, kinds=中华田园猫] Cat [name=小花, month=12, kinds=英国短毛猫]


小花找到了! Cat [name=小花, month=12, kinds=英国短毛猫]


小花花没找到


Cat [name=小凡, month=3, kinds=中华田园猫]

### 1.6.4 Set不可重复性
由于HashSet中不允许添加重复元素,调用add方法时使用hashCode和equals方法判断元素是不同的。
- 添加数据时,会调用hashCode方法得到hash code的值,通过这个值可以找到数据存储的位置,这个位置可以理解为一片区域,在该区域中存储的数据hash code都是相等的
- 如果该区域已经有数据了,就继续调用equals()方法判断数据是否相等,如果相等就说明重复了,就不允许添加,如果hash code值不等,就找一个区域进行存储。
- 如果需要比较两个对象是否相等,则必须同时覆盖对象的hashCode方法和equals方法,并且hashCode方法和equals方法的返回值必须相同。
- 如果一个类没有覆盖hashCode()和equals()方法,则它的equals()方法执行的是引用相等性的比较。

【如果两个对象hashCode值不同,则两个对象必然不同】
### 1.6.5 getClass()和.class
在上述代码重写equals时用到了getClass()和.class,这里作个说明:getClass()是Object类的方法,该方法的返回值类型是Class类,通过getClass()方法可以得到一个Class类的对象。而.class返回的也是Class类型的对象。所以,如果obj.getClass()和Cat.class返回的内容相等,说明是同一个对象。

既然都可以得到Class的对象,关于getClass()和.class的区别:getClass()方法,有多态能力,运行时可以返回子类的类型信息。.class是没有多态的,是静态解析的,编译时可以确定类型信息。    
## 1.7 集合——Map   
- Map中的数据是以键值对(key-value)的形式存储的。
- key-value以Entry类型的对象实例存在。
- 可以通过key值快速地查找value,一个值可以有多个键。
- 一个映射不能包含重复的键。
- 每个键最多只能映射到一个值。

**Map中最常用实现类HashMap,HashSet是在HashMap基础上实现的。**
- 基于哈希表 Map接口的实现;
- 允许使用null值和null键,由于键不能重复,所以只能有一个null键;
- key值不能重复;
- HashMap中Entry对象是无序排列的(除了List都是无序)。
### 1.7.1 使用HashMap实现数据存储和输出

package person.xsc.practice; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class MapDemo { public static void main(String[] args) { // TODO Auto-generated method stub HashMap<String,String> has = new HashMap<String,String>(); has.put("English", "英语"); has.put("Math", "数学"); has.put("Chinese", "语文"); System.out.println("打印输出value的值(直接使用迭代器)"); Iterator iter = has.values().iterator(); while (iter.hasNext()) { System.out.println(iter.next()); } System.out.println("****"); System.out.println("打印输出key的值(直接使用迭代器),使用keySet()方法获取所有的key值"); Iterator it=has.keySet().iterator(); while (it.hasNext()){ System.out.println(it.next()); } System.out.println("****"); System.out.println("打印输出key和value的值:通过entrySet方法"); /** * Map.Entry是Map中的一个接口,他的用途是表示一个映射项(里面有K和V),而Set<Map.Entry<k,V>> * 表示一个映射项的Set。然后就可以从Map.Entry中的getKey方法和getValue方法中取出Key和Value。
/ Set<Map.Entry<String, String>> entrySet = has.entrySet(); for (Map.Entry<String ,String> entry:entrySet) { System.out.print(entry.getKey()+"-"); System.out.println(entry.getValue()); } System.out.println("***"); System.out.println("打印输出key和value的值:通过默认的toString方法"); System.out.println(has); System.out.println("****"); System.out.println("打印输出key和value的值:通过get() 方法获取指定 key 对应对 value。"); Set keys = has.keySet(); for (Object key : keys) { System.out.println(key + "=" + has.get(key)); } System.out.println("****"); System.out.println("根据指定key 取value"); String str1="Chinese"; for(Map.Entry<String,String> str : has.entrySet()){ if(str1.equals(str.getKey())){ System.out.println(str1+"对应的value值为:"+str.getValue()); } }
} } 输出: 打印输出value的值(直接使用迭代器) 英语 语文 数学


打印输出key的值(直接使用迭代器),使用keySet()方法获取所有的key值 English Chinese Math


打印输出key和value的值:通过entrySet方法 English-英语 Chinese-语文 Math-数学


打印输出key和value的值:通过默认的toString方法 {English=英语, Chinese=语文, Math=数学}


打印输出key和value的值:通过get() 方法获取指定 key 对应对 value。 English=英语 Chinese=语文 Math=数学


根据指定key 取value Chinese对应的value值为:语文

### 1.7.2 泛型的概念
泛型是参数化类型,一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

泛型的好处是在编译时检查类型安全,并且所有的强制转换都是自动和隐式的,提高了代码的重用率,避免在运行时出现 ClassCastException。
下面来看一段代码:

package person.xsc.practice; import java.util.ArrayList; public class FanXingTest { public static void main(String[] args) { // TODO Auto-generated method stub ArrayList arrayList=new ArrayList(); arrayList.add(888); arrayList.add("HelloWorld"); for(int i=0;i<arrayList.size();++i) { String str=(String) arrayList.get(i); System.out.println(str);
} } }

上面这段代码,编译器没有报任何错误,但是当我运行的时候,输出了下面异常:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String at person.xsc.practice.FanXingTest.main(FanXingTest.java:17)

ArrayList可以存放任意类型,就像上面代码我添加了一个String类型,然后又添加了一个Integer类型,然后再使用String来定义并强制转换,在编译阶段就无法发现问题,为了可以在编译阶段发现类似问题并解决,泛型应运而生。

下面我将上面代码修改一下,编译器会在编译阶段就能够帮我发现类似问题。
![image](https://img-hello-world.oss-cn-beijing.aliyuncs.com/imgs/7e0b0107a89dd4b9e0a8ac68f61d9bc8.png)

关于更多的泛型知识就不在这里一一阐述了,有兴趣的可以去社区里搜索下面几篇文章:
- java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一
- 死磕Java泛型(一篇就够)
### 1.7.3 案例实现(商品管理)
**需求**
➩ 使用HashMap对商品信息进行管理【其中key为商品编号,value为商品对象】
➩ 对HashMap中的商品信息进行增、删、改、查操作
- **第一步 商品类的定义**

package person.xsc.practice; public class Goods { private String id; private String name; private double price; public Goods() {

}
public Goods(String id,String name,double price) {
    this.id=id;
    this.name=name;
    this.price=price;
}
public String getId() {
    return id;
}
public void setId(String id) {
    this.id = id;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public double getPrice() {
    return price;
}
public void setPrice(double price) {
    this.price = price;
}
@Override
public String toString() {
    return "Goods [id=" + id + ", name=" + name + ", price=" + price + "]";
}

}

- **第二步,测试类的定义**

package person.xsc.practice; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Scanner; import java.util.Set; public class GoodsTest { public static void main(String[] args) { // TODO Auto-generated method stub Scanner console=new Scanner(System.in); //定义HashMap对象 Map<String,Goods> goodsMap=new HashMap<String,Goods>(); System.out.println("请输入三条商品信息:"); int i=0; while (i<3){ System.out.println("请输入第"+(i+1)+"条商品编号:"); String goodsId=console.next(); if (goodsMap.containsKey(goodsId)) { System.out.println("该商品编号已经存在!请重新输入!"); continue; } System.out.println("请输入第"+(i+1)+"条商品名称:"); String goodsName=console.next(); while (true) { System.out.println("请输入第"+(i+1)+"条商品价格:"); double goodsPrice = 0; try { goodsPrice = console.nextDouble(); } catch (java.util.InputMismatchException e) { System.out.println("商品价格的格式不正确,请输入数值型数据!"); console.next(); //输入错误,跳过此循环,进行下一次循环,提示输入价格 continue; } //把商品的信息组成一个商品的对象,再添加到hachmap中 Goods goods=new Goods(goodsId,goodsName,goodsPrice); goodsMap.put(goodsId,goods); i++; //输入正确,将商品信息添加到map中,使用break结束里面的循环,继续执行整体的循环 break; } } System.out.println("****"); //遍历Map输出商品信息 System.out.println("商品全部信息为:"); //把value值存储到迭代器中 Iterator itGoods=goodsMap.values().iterator(); while(itGoods.hasNext()){ System.out.println(itGoods.next()); } System.out.println("****"); Set setGoodsID = goodsMap.keySet(); System.out.println("请输入你要修改的商品名称:"); String ChangePriceName=console.next(); for(Object s:setGoodsID){ if(goodsMap.get(s).getName().equals(ChangePriceName)){ System.out.println("请输入新的商品价格:"); double newPrice=console.nextDouble(); goodsMap.get(s).setPrice(newPrice); break; } } System.out.println("商品全部信息为:"); System.out.println(goodsMap); System.out.println("****"); //清空所有的商品 goodsMap.clear(); System.out.println("清空后的商品全部信息为:"); if(goodsMap.size()==0) { System.out.println("商品集合已经清空,没有数据了!"); }else { System.out.println(goodsMap); }

}

}

输出: 请输入三条商品信息: 请输入第1条商品编号: G001 请输入第1条商品名称: 笔记本 请输入第1条商品价格: 18.5 请输入第2条商品编号: G002 请输入第2条商品名称: 钢笔 请输入第2条商品价格: 999.8 请输入第3条商品编号: G003 请输入第3条商品名称: 橡皮 请输入第3条商品价格: 1.5


商品全部信息为: Goods [id=G002, name=钢笔, price=999.8] Goods [id=G001, name=笔记本, price=18.5] Goods [id=G003, name=橡皮, price=1.5]


请输入你要修改的商品名称: 笔记本 请输入新的商品价格: 16.8 商品全部信息为: {G002=Goods [id=G002, name=钢笔, price=999.8], G001=Goods [id=G001, name=笔记本, price=16.8], G003=Goods [id=G003, name=橡皮, price=1.5]}


清空后的商品全部信息为: 商品集合已经清空,没有数据了!

```

1.8 关于集合的面试问题

  • List, Set, Map是否继承自Collection接口? List,Set是,Map不是。
  • 如果两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对 不对,两个对象值相同(x.equals(y) == true),则一定有相同的hash code。Java对于eqauls方法和hashCode方法是这样规定的:
  1. 如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同;
  2. 如果两个对象的hashCode相同,它们并不一定相同。
  • List、Map、Set三个接口,存取元素时,各有什么特点? List 以特定次序来持有元素,可有重复元素。Set 无法拥有重复元素,内部排序。Map 保存key-value值,value可多值。
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这