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. C++学习(五)(C语言部分)之 运算符

    运算符学习时的笔记(其实也没什么用,留着给自己看的) 运算符 用来对数据运算的符号 优先级 3+4*5+6 先乘除 然后加减 运算符优先级高就先算 40多个运算符 15层优先级 不需要背 1.查表 2 ...

  2. 实验吧—隐写术——WP之 Fair-Play

    首先,我们读题发现题目是Playfair​,其实我也不知道这是什么,那么就百度一下啊 Playfair解密算法: 首先将密钥填写在一个5*5的矩阵中(去Q留Z),矩阵中其它未用到的字母按顺序填在矩阵剩 ...

  3. hdu2389 Rain on your Parade 二分图匹配--HK算法

    You’re giving a party in the garden of your villa by the sea. The party is a huge success, and every ...

  4. IDEA在jsp页面写out.print()代码报错

    如题,小编以前用myeclipse,eclipse的时候,在jsp里写java代码都是可以的,现在我换成了IDEA,却莫名报错 而且没有代码提示,比如说下图这样的,,虽然运行还是能运行...但对强迫症 ...

  5. Go Example--原子计数器

    package main import ( "fmt" "runtime" "sync/atomic" "time" ) ...

  6. loki grafana 团队开源的,类似Prometheus 的log 系统

    Prometheus 主要面向的是metrics,但是loki 是log,这样加上grafana 强大的可视化以及alert能力, 我们可以做好多事情,loki 的设计来源于Prometheus. 组 ...

  7. httpd

    http://httpd.apache.org/docs/2.2/logs.html httpd.conf文件 Configuration and logfile names: If the file ...

  8. 代理模式proxy

    代理模式的共同优点如下: (1) 能够协调调用者和被调用者,在一定程度上降低了系统的耦合度. (2) 客户端可以针对抽象主题角色进行编程,增加和更换代理类无须修改源代码,符合开闭原则,系统具有较好的灵 ...

  9. 二维指针的malloc内存分配(转)

    写代码的时候会碰到多维数组的内存分配和释放问题,在分配和释放过程中很容易出现错误.下面贴上一些示例代码,以供参考. 如果要给二维数组(m*n)分配空间,代码可以写成下面: char **a, i; 1 ...

  10. java 加载数据库驱动

    JDBC编程步骤见 JDBC编程步骤 JDBC编程的第一步是加载数据库驱动,使用Class类的forName()方法,Class.forName("com.mysql.jdbc.Driver ...