List是一种有序链表:

  • List内部按照放入元素的先后顺序存放
  • 每个元素都可以通过索引确定自己的位置
  • boolean contains(Object o) 是否包含某个元素
  • int indexOf(Object o) 查找某个元素的索引,不存在返回-1

1.String\Integer等已经覆写了equals方法

import java.util.*;

public class Main {
public static void main(String[] args){
List<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add(null);
list.add(3,"java");
list.add(4,"python");
System.out.println(list.toString()+"是否包含null:"+list.contains(null));
System.out.println(list.toString()+"是否包含hello:"+list.contains("hello"));
System.out.println(list.toString()+"是否包含ruby:"+list.contains("ruby"));
System.out.println(list.toString()+"hello的索引::"+list.indexOf("hello"));
System.out.println(list.toString()+"ruby的索引:"+list.indexOf("ruby"));
}
}


问题:list.add("hello")和list.contains("hello"))是不是一个实例?如果不是,是否依然可以使用contains方法 ?
```#java
//先确保不是一个实例
List list = new ArrayList();
list.add(new String("C"));
System.out.println(list.contains(new String("C")));
```

原因:List内部使用equals方法判断2个元素是否相同
```#java
//演示代码
public class ArrayList{
Object[] elementData;
public boolean contains(Object o){
for(int i=0;i2.重写equals方法

Person.java

package com.testList;

public class Person {
private String name;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
@Override
public String toString(){
return "(Person:"+name+","+age+")";
}
}

Main.java

import java.util.*;

public class Main {
public static void main(String[] args){
List<Person> list = new ArrayList<>();
list.add(new Person("小明",12));
list.add(new Person("小红",15));
list.add(new Person("小军",13));
System.out.println(list);
System.out.println(list.contains(new Person("小军",13)));
}
}

在Person类中并没有覆写Objects.equals()方法,此时equals使用==来判断2个Object的引用,因此contains返回是false。为了修复这个逻辑,使contains返回true,此时要编写equals方法

重写equals方法

public boolean equals(Object o){
if (this == o){
return true;
}
if (o instanceof Person){
Person p = (Person) o;
return p.name.equals(this.name) && p.age == this.age;
}
return false;
}
        System.out.println(list.contains(new Person("小红",15)));


当传入的name为null时,会报java.lang.NullPointerException
```#java
list.add(new Person(null,15));
System.out.println(list.contains(new Person(null,15)));
```

```#java
//为了解决java.lang.NullPointerException
public boolean equals(Object o){
if (this == o){ //判断传入的对象o是不是当前的对象this
return true;
}
if (o instanceof Person){ //判断传入的对象o是不是Person类型
Person p = (Person) o;
return (p.name == this.name||p.name != null && p.name.equals(this.name)) && p.age == this.age;

    }
return false;
}
<img src="https://img2018.cnblogs.com/blog/1418970/201903/1418970-20190311200855542-421064474.png" width="500" />

使用JDK Objects自带的equals方法精简代码
```#java
public boolean equals(Object o){
if (this == o){
return true;
}
if (o instanceof Person){
Person p = (Person) o;
return Objects.equals(p.name,this.name) && p.age == this.age; }
return false;
}

总结:

如果要在List中查找元素:

  • List的实现类通过元素的equals方法比较两个元素
  • 放入的元素必须正确覆写equals方法

    * jdk提供的String、Integer等已经覆写了equals方法
  • 编写equals方法可借助Objects.equals()判断

如果不在List中查找元素:

  • 不必覆写equals方法

廖雪峰Java5集合-2List-2编写equals方法的更多相关文章

  1. 廖雪峰Java5集合-3Map-1使用Map

    廖雪峰的视频不全,以下是疯狂Java关于Map的讲解 1.Map定义 Map是一种键值映射表,可以通过key快速查找value,同python的dict.key不允许重复,value可以重复. Map ...

  2. 廖雪峰Java5集合-4Set-1使用Set

    集合 Set用于存储不重复的元素集合: boolean add(E e) boolean remove(Object o) boolean contains(Object o) int size() ...

  3. 廖雪峰Java5集合-3Map-Properties的使用

    Properties用于读取配置 properties文件只能使用ASCII码 #表示注释 可以从文件系统读取.properties文件 Properties props = new Properti ...

  4. 廖雪峰Java5集合-1Java集合简介-1Java结合简介

    1.集合 定义:集合就是一堆东西.集合里的东西,称为元素Element 数学中的集合: 有限集合: * 一个班所有的学生组成的集合 * 一个网站所有的商品组成的集合 无限集合: * 全体自然数集合 * ...

  5. 廖雪峰Java5集合-6Stack-1使用Stack

    1.栈的定义 栈Stack是一种后进先出(LIFO: Last In First Out)的数据结构,可以看作一端封闭的容器,先进去的元素永远在底部,最后出来. 栈有2个重要的方法: push(E e ...

  6. 廖雪峰Java5集合-2List-1使用List

    1.List定义 List是一种有序链表: List内部按照元素的先后顺序存放 每个元素都可以通过索引确定自己的位置 类似数组,但大小可变 //List<E>是一种有序链表: //* Li ...

  7. 重新编写equals()方法,hashCode()方法,以及toString(),提供自定义的相等标准,以及自描述方法

    下面给出一个实例,重新编写equals()方法,提供自定义的相等标准 public class PersonTest { public static void main(String[] args) ...

  8. 廖雪峰Java5Java集合-5Queue-1使用Queue

    Queue特性和基本方法 Queue实现一个先进先出(FIFO, First In First Out)的队列.如收银台排队支付. Java中LinkedList实现了Queue接口,可以直接把Lin ...

  9. 廖雪峰Java16函数式编程-1Lambda表达式-3方法引用

    Java8引入了Lambda表达式,可以不必编写FunctionalInterface的实现类,直接写Lambda表达式.除了Lambda表达式,我们还可以直接传入方法引用 方法引用是指:如果某个方法 ...

随机推荐

  1. 【BZOJ3514】 Codechef MARCH14 GERALD07加强版

    hentai... 原题: N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 对于100%的数据,1≤N.M.K≤200,000. 直接复制wulala的题解 wulal ...

  2. rpm使用

    查找某个rpm包是否安装 rpm -qa|grep 包名 #我们再次安装是会提示和那个包冲突,直接复制那个报名过来就可 安装rpm包 rpm -ivh 报名

  3. <--------------------------Java继承及抽象类------------------------------>

    1 继承的好处   关键词-->extends 1.1.继承的出现提高了代码的复用性,提高软件开发效率. 1.2.继承的出现让类与类之间产生了关系,提供了多态的前提. 2 继承的注意事项 *a: ...

  4. java.lang.NoClassDefFoundError: org/apache/jute/CsvOutputArchive

    1. 问题 看到上面的错误 你怎么想? 包冲突?我这里不是.项目用到了zookeeper,这个类是zookeeper的核心包里的类. 控制台一直打印这个错误 但是项目不影响使用,奇怪! 2. 解决办法 ...

  5. 著名软件工程师与作家、极限编程的创始者、JUnit作者之Kent Beck

    Kent Beck,1961年出生,中文名肯特贝克,美国著名软件工程师与作家,在软件工程方面有很大的贡献.他是Smalltalk软件的开发者,设计模式的先驱,测试驱动开发的支持者,也是极限编程的创始者 ...

  6. Spring技术内幕总结 - IoC容器的实现

    IoC:Inversion of Control,控制反转,即依赖对象的获得被反转了(DI:dependency inversion,依赖注入)在Spring中,IoC容器是实现这个模式的载体.它可以 ...

  7. webpack 学习资料

    webpack 学习资料 webpack 学习资料 网址 webpack 中文版 https://webpack.docschina.org/configuration/dev-server/

  8. Jmeter--报错 WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.

    今天要用Jmeter测试服务器性能,发现GUI界面总是有warning提示: WARNING: Could not open/create prefs root node Software\JavaS ...

  9. piwik高负载加速之切换session存储位置

    默认情况下,piwik的session是存储于根目录下面的tmp/sessions/路径下面的.而官方文档里面说,如果由于本地硬盘的原因,这种设置可能会导致系统被变慢,这在高负载系统应用中可能是不可以 ...

  10. debian的python蓝牙库

    sudo apt--dev pip install bluepy