java基础之集合——Collection集合

2 篇文章 0 订阅

集合

数组其实就是一个集合。集合实际上就是一个容器。可以来容纳其它类型的数据。

集合和数组有什么区别?

1)长度区别
数组:长度固定
集合:长度可变

2)存储数据类型的区别
数组:可以存储基本数据类型,也可以存储引用数据类型
集合:前提条件:集合中加入泛型<>
也是在模拟数组的特点:只能存储引用类型 Collection :泛型<引用类型>

3)存储元素的区别:
数组:存储的元素必须为同一种数据类型
集合:如果没有加入泛型 :就出任意类型的元素(必须引用类型)

集合框架

基本功能:

添加
boolean add(Object e):添加元素  E(Element)

删除:
void clear() 暴力删除(将集合的素有元素全部干掉)
boolean remove(Object o):从集合中删除指定的元素
获取集合的元素数 :int size()

判断功能:
boolean isEmpty():判断集合是否为空,为空元素,则返回true
boolean contains(Object o):判断集合中是否包含指定元素,包含则返回true

Collection接口:

在这里插入图片描述

Map接口

在这里插入图片描述

Collection集合的高级功能

boolean addAll(Collection c);//添加一个集合中的所有元素
boolean containsAll(Collection c);//包含一个集合中的所有元素
boolean removeAll(Collection c);//删除集合中的所有元素, (删除一个算删除,还是删除所有)
boolean retainAll(Collection c);//A集合对B集合求交集, boolean的返回值是什么意思,交集的元素是保存在A中还是B中

//Collection最基本的遍历功能,不属于集合的专有遍历
Object[] toArray();//将集合转换成了对象数组

迭代器

Collection的迭代器:集合的专有遍历方式

Iterator iterator();//返回值类型接口类型,需要返回的子实现类对象

//Iterator接口:
boolean hasNext();//判断迭代器中是否存在下一个元素
Object next();//获取下一个可以遍历的元素
//给Collection中存储String类型,遍历出来

eg,

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Scanner;

public class Test01 {

    public static void main(String[] args) {

        Collection<Student> collection = new ArrayList<Student>();

        collection.add(new Student("老王",34));
        collection.add(new Student("老张",41));
        collection.add(new Student("老梁",52));
        collection.add(new Student("老刘",35));
        collection.add(new Student("老李",61));

        for (Object object : collection) {
            Student s = (Student) object;
            System.out.println(s.toString() + "学生");
            System.out.println(object.toString() + "toString");

            /*
            Iterator<Student> iterator = collection.iterator();
            while(iterator.hasNext()){
            Object object = iterator.next();
            Student s = (Student)object;
            System.out.println(s.toString()+"学生");
            System.out.println(object.toString()+"toString");
             */
        }

    }

}

class Student{

    String name;
    int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

运行结果:

Student{name=‘老王’, age=34}学生
Student{name=‘老王’, age=34}toString
Student{name=‘老张’, age=41}学生
Student{name=‘老张’, age=41}toString
Student{name=‘老梁’, age=52}学生
Student{name=‘老梁’, age=52}toString
Student{name=‘老刘’, age=35}学生
Student{name=‘老刘’, age=35}toString
Student{name=‘老李’, age=61}学生
Student{name=‘老李’, age=61}toString

迭代器原理

内部具备一个指针,当在第一次获取元素的时候,指针处在第一个元素前面的位置,不指向任何元素,当通过hasNext()判断,如果存在下一个可以迭代的元素,那么指针就会向下一个索引进行移动,并且next()获取前面的元素,依次这样操作,直到hasNext()为false的时候,没有元素了,指针就不会在移动;Iterator是一个接口,具体的移动的操作是通过ArrayList的成员内部类Itr来进行实现;

泛型

格式:

集合类型<引用数据类型>  集合对象名 = new  子实现类<引用数据类型>() ;

泛型的好处:

1)将运行时期异常提前了编译时期

2)避免了强制类型转换

3)提高了程序安全性

eg.使用Collection集合存储5个学生,加入泛型 Collection,使用迭代器遍历并获取

public class GenericDemo {
    public static void main(String[] args) {

        //创建Collection集合对象
        Collection<String> c = new ArrayList<String>() ; //new XXX<数据类型>: jdk7以后泛型推断

        c.add("hello") ;
        c.add("高圆圆") ;
        c.add("你好吗") ;

        //获取迭代器Iteratr<E>是集合中存储的泛型是一致的
        Iterator<String> it = c.iterator();
        while(it.hasNext()){
            //获取String字符串的同时,还要获取长度
            String str = it.next();
            System.out.println(str+"---"+str.length());
        }
    }
}

List集合

特点

有序(存储元素和取出元素一致)
允许元素重复

具备Collection相关的功能

Object [] toArray()
Iterator iterator()

特有功能

void add(int index,Object element):在指定的索引处插 入元素
Object get(int index):获取指定位置处的元素  + int size():一种新的集合遍历方式
Object remove(int index):删除指定位置处的元素
Object set(int index,E element):修改指定位置处的元素(替换)

ListIterator<E> listIterator():列表迭代器
ListIterator接口:
void add(E e)有添加
remove():有删除

特有功能
void add(int index,Object element):在指定的索引处插 入元素
Object get(int index):获取指定位置处的元素 + int size():一种新的集合遍历方式
Object remove(int index):删除指定位置处的元素
Object set(int index,E element):修改指定位置处的元素(替换)

ListIterator listIterator():列表迭代器
ListIterator接口:
void add(E e)有添加
remove():有删除

集合的遍历

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class Test01 {

    public static void main(String[] args) {

        List<Person> list = new ArrayList<Person>();

        list.add(new Person("老大", 12));
        list.add(new Person("老二", 11));
        list.add(new Person("老三", 10));

        //①toArray
        Object[] objects = list.toArray();
        for (int i = 0; i < objects.length; i++) {
            Person person = (Person) objects[i];
            System.out.println(person.toString());
        }

        System.out.println("————————");

        //②get/set
        Object[] objects1 = list.toArray();
        for (int i = 0; i < objects1.length; i++) {
            Person person = (Person) objects[i];
            System.out.println(person.getName()+"----"+person.getAge());
        }

        System.out.println("————————");

        //③迭代器
        Iterator<Person> iterator = list.iterator();
        while (iterator.hasNext()) {
            Person p = iterator.next();
            System.out.println(p.toString());
        }

        System.out.println("————————");

        //④list迭代器
        ListIterator<Person> iterator1 = list.listIterator();
        while (iterator1.hasNext()) {
            Person p = iterator1.next();
            System.out.println(p.toString());
        }

        System.out.println("————————");

        while (iterator1.hasPrevious()) {
            Person p = iterator1.previous();
            System.out.println(p);
        }

        System.out.println("————————");

        //⑤增强for
        for (Person p : list) {
            System.out.println(p);
        }

    }

}

class Person {

    String name;
    int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

运行结果:

Person{name=‘老大’, age=12}
Person{name=‘老二’, age=11}
Person{name=‘老三’, age=10}
————————
老大----12
老二----11
老三----10
————————
Person{name=‘老大’, age=12}
Person{name=‘老二’, age=11}
Person{name=‘老三’, age=10}
————————
Person{name=‘老大’, age=12}
Person{name=‘老二’, age=11}
Person{name=‘老三’, age=10}
————————
Person{name=‘老三’, age=10}
Person{name=‘老二’, age=11}
Person{name=‘老大’, age=12}
————————
Person{name=‘老大’, age=12}
Person{name=‘老二’, age=11}
Person{name=‘老三’, age=10}

并发修改异常

通过List集合ArrayList集合对象,如果当前集合中存在"world"元素,那么就给集合中添加一个"javaEE"元素,最后将集合中的所有元素进行遍历!

问题描述

当集合的元素正在被迭代器进行遍历,那么集合对象是不能够对元素进行增加或者删除 (一个线程正在遍历,一个线程在修改元素)

解决方案

1)要么就是迭代器去遍历集合的元素,迭代器去添加元素 :列表迭代器才具备添加的动作
2)要么集合遍历,集合添加

eg.

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class Test02 {

    public static void main(String[] args) {

        List<String> list = new ArrayList<String>();

        list.add("helo");
        list.add("world");
        list.add("java");

        /*
        Iterator<String> iterator = list.iterator();
        while(iterator.hasNext()){
            String s = iterator.next();//java.util.ConcurrentModificationException并发修改异常
            if("world".equals(s)){
                list.add("javaee");
            }
            System.out.println(list);
        }
        会报错
        [helo, world, java]
        [helo, world, java, javaee]
        Exception in thread "main" java.util.ConcurrentModificationException
       at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
       at java.util.ArrayList$Itr.next(ArrayList.java:851)
       at HemoWork.day19.ClassTest.ListTest.Test02.main(Test02.java:19)
         */

        //解决方法1
        //用迭代器添加
        ListIterator<String> it = list.listIterator();
        while (it.hasNext()) {
            String s = it.next();
            if ("world".equals(s)) {
                //迭代器添加
                it.add("javaee");
            }

        }
        System.out.println(list);

        System.out.println("-------------");

        //解决方法2
        //用集合添加(只能加到末尾
        for (int i = 0; i < list.size(); i++) {
            String string = list.get(i);
            if("world".equals(string)){
                list.add("javaee");
            }

        }
        System.out.println(list);
    }

}

运行结果:

[helo, world, javaee, java]

[helo, world, javaee, java, javaee]

foreach

JDK5以后 提供了增强for循环,替代集合中迭代器去遍历集合使用的(优先在集合中使用)

格式:
 for(存储的引用数据类型 变量名: 集合/数组对象){ //集合使用居多,数组一般都是使用普通for
    使用变量名即可
 }
注意事项:

当前集合对象不能为空 null :foreach语句;

增强for它本身就是获取迭代器了,就会出现空指针异常

cantions方法

List集合如何去重?

eg.1

import java.util.ArrayList;
import java.util.List;

public class Test03 {

    public static void main(String[] args) {

        List<String> list = new ArrayList();

        list.add("hello");
        list.add("hello");
        list.add("hello");
        list.add("hello1");
        list.add("hello");
        list.add("hello3");
        list.add("hello");
        list.add("hello");
        list.add("hello5");
        list.add("hello");

        //去重
        //方法一:新建一个空集合,
        List<String> newlist = new ArrayList<>();

        for (String s : list) {
            if (!newlist.contains(s)) {
                newlist.add(s);
            }
        }

        for (String s2 : newlist) {
            System.out.println(s2);
        }

        list.add("hello");
        list.add("hello");
        list.add("hello");
        list.add("hello1");
        list.add("hello");
        list.add("hello3");
        list.add("hello");
        list.add("hello");
        list.add("hello5");
        list.add("hello");

        System.out.println("——————————");

        //方法二:利用选择排序的思想
        //两辆比较
        for (int i = 0; i < list.size(); i++) {
            for (int j = i + 1; j < list.size(); j++) {
                if (list.get(i).contains(list.get(j))) {
                    list.remove(j);
                    j--;
                }
            }
        }

        for (String s2 : list) {
            System.out.println(s2);
        }

    }

}

运算结果:

hello
hello1
hello3
hello5
——————————
hello
hello1
hello3
hello5

eg.2

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class Test04 {

    public static void main(String[] args) {

        List<Student> list = new ArrayList();

        list.add(new Student("老大"));
        list.add(new Student("老大"));
        list.add(new Student("老二"));
        list.add(new Student("老大"));
        list.add(new Student("老三"));
        list.add(new Student("老大"));

        //新建集合
        List<Student> newList = new ArrayList<>();

        for (Student student : list) {
            if (!newList.contains(student)) {
                newList.add(student);
            }
        }

        for (Student s : newList) {
            System.out.println(s);
        }

        System.out.println("————————————");

        //选择排序思想
        list.add(new Student("老大"));
        list.add(new Student("老大"));
        list.add(new Student("老二"));
        list.add(new Student("老大"));
        list.add(new Student("老三"));
        list.add(new Student("老大"));

        for (int i = 0; i < list.size()-1; i++) {
            for (int j = i+1; j < list.size(); j++) {
                if(list.get(i).getName().contains(list.get(j).getName())){
                    list.remove(j);
                    j--;
                }
            }
        }

        for (Student s : list){
            System.out.println(s);
        }

    }

}

class Student {

    String name;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student student = (Student) o;

        return name.equals(student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                '}';
    }
}

运行结果:

Student{name=‘老大’}
Student{name=‘老二’}
Student{name=‘老三’}
————————————
Student{name=‘老大’}
Student{name=‘老二’}
Student{name=‘老三’}

list子实现类的特点

ArrayList

ArrayList集合初始化容量10

扩容为原容量1.5倍。

底层是数组,查询快,增删慢

另外要注意:ArrayList集合末尾增删元素效率还是可以的。

线程角度: 线程不安全的类,实现不同步的 ----->执行效率高

Vector

Vector初始化容量是10.

扩容为原容量的2倍。

底层是数组,查询快,增删慢

Vector底层是线程安全的。

线程角度:线程安全的类----同步的方法---->执行效率低

怎么得到一个线程安全的List:
Collections.synchronizedList(list);

单线程程序中.考虑集合默认都会使用 ArrayList,多线程环境集合---->Vector集合

LinkedList

底层数据结构是链表,查询慢,增删快

线程角度:线程不安全的类---->不同步---->执行效率高

特有功能:

addFirst()
removeFirst()
getFirst()

xxxLast()
应用场景:模拟栈结构特点,先进后出

 如果没有明确要求使用什么(List)集合的时候 ,默认都是用ArrayList

Vector类

特有功能:
public void addElement(Object obj);//在vector对象的末尾添加元素  ------> 一直使用的add(Object e)
删除
public boolean removeElement(Object obj);//删除元素
获取功能
public Object elementAt(int index);//获取指定位置的元素---->类似于  public Object get(int index)
public Enumeration<E> elements();//Vector集合的专有遍历方式---->类似于   Iterator literator();接口
boolean hasMoreElements();//判断是否有更多的元素可以迭代
Object nextElement();//获取元素

eg.

import java.util.ArrayList;
import java.util.List;

public class Test01 {

    public static void main(String[] args) {
        //创建List集合对象
        List<String> list = new ArrayList<String >();

        //添加元素
        list.add("hello") ;
        list.add("hello") ;
        list.add("world") ;
        list.add("world") ;
        list.add("world") ;
        list.add("javaEE") ;
        list.add("javaEE") ;

        // void add(int index,Object element):在指定的索引处插 入元素
        list.add(1,"高圆圆");
        
        //Object get(int index):获取指定位置处的元素 :返回的被获取到的元素内容
        System.out.println(list.get(1));

        //  Object remove(int index):删除指定位置处的元素,返回被删除的元素
        System.out.println(list.remove(2));

        //Object set(int index,E element):修改指定位置处的元素(替换)
        System.out.println(list.set(1,"赵又廷"));
        System.out.println(list);
    }

}

直接插入排序

核心思想:使用1角标对应的元素进行和0角标比较,如果前面元素大,向右移动,确定角标1对应的元素的位置,再次使用2角标对应的元素依次和1和0都元素比较,依次这样比较。

/*
Integer类:包含了int类型的值:
Integer实现自然排序(默认升序排序)
*/

public int compareTo(Integer anotherInteger) {
     return compare(this.value, anotherInteger.value);
}

public static int compare(int x, int y) {  //提高程序的执行效率
     return (x < y) ? -1 : ((x == y) ? 0 : 1);
}

eg.

public class InsertSort {

    public static void main(String[] args) {

        int[] arr = {34, 8, 64, 51, 32, 21};

        System.out.println("排序前:");
        printArr(arr);

        System.out.println("排序后:");
        insertSort(arr);


    }

    private static void printArr(int[] arr) {

        System.out.print("[");
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length - 1) {
                System.out.println(arr[i] + "]");
            } else {
                System.out.print(arr[i] + ",");
            }
        }

    }

    private static void insertSort(int[] arr) {

        //定义一个变量,记录当前角标的变化
        int index;

        //定义变量:P表示一个比较次数
        for (int p = 0; p < arr.length; p++) {

            //定义临时变量temp
            Integer temp = arr[p];//temp = 8;temp = 64

            //开始比较
            for (index = p; index > 0 && temp.compareTo(arr[index - 1]) < 0; index--) {
                // j=1 ; 1>0 &&  8 < 34   j-- : j= 0
                // j=2 ; 2>0 && 64 < 32
                //数据移动
                arr[index] = arr[index - 1];
            }

            //确定temp的位置
            arr[index] = temp;

        }

        printArr(arr);
    }

}

运行结果:

排序前:
[34,8,64,51,32,21]
排序后:
[8,21,32,34,51,64]

LinkedList类

集合特点:

线程不安全,执行效率较高,是个列表结构

特有功能:
public void addFirst(0bject e):在列表开头插入元素
pub1ic void addLast(0bject e):将元素追加到列表的末尾
public 0bject getFirst(): 获取列表的第一个元 素
public 0bject getLast():获取 列表的最后一 个元素
public 0bject removeFirst(): 删除列表的第个元素
public 0bject removeLast() :删除列表的最后一个元素

push压栈
pop弹栈
利用Linkedlist模拟栈数据结构:
import java.util.LinkedList;
//栈方法类
public class MyStack {

    private LinkedList<Object> link;

    //空参构造
    public MyStack() {
        link = new LinkedList<Object>();
    }

    public MyStack(LinkedList<Object> link) {
        this.link = link;
    }

    //添加方法
    public void add(Object o) {
        link.addFirst(o);
    }

    //获取获取元素
    public void get(){
        System.out.println(link.removeFirst());
    }

    //判断是否为空
    public void isEmpty(){
        if (link.isEmpty()){
            System.out.println("栈为空");
        }else {
            System.out.println("栈不为空");
        }

    }

    public LinkedList getLink() {
        return link;
    }

    public void setLink(LinkedList link) {
        this.link = link;
    }
}
//工具类
public class Test01 {
    public static void main(String[] args) {

        //创建对象
        MyStack stack = new MyStack();

       	//压栈
        stack.add("sad");
        stack.add(123);
        stack.add(1.2234);
        stack.add(true);

        //判断是否为空
        stack.isEmpty();

        //弹栈
        stack.get();
        stack.get();
        stack.get();
        stack.get();

        //判断是否为空
        stack.isEmpty();

    }
}

运行结果:

栈不为空
true
1.2234
123
sad
栈为空

HashSet类

底层数据结构是一个哈希表

线程不安全的类---->不同步---->执行效率高

Set集合特点:

无序(存储和取出不一致),能够保证元素唯一

JUC(java.util.concurrent)

JDK8以后,提供了juc(并发包:java.util.concurrent):
ConcurrentHashMap<K,V>和HashMap的区别 ?

前者线程安全,后者线程不安全

hashCode方法及equals方法

String类型:String类型本身已经重写了hashCode()和equals,如果hashCode和equals()都相同,那么认为同一个元素,存储以前的值

如果现在存储是自定义对象,如何保证元素唯一?
HashSet<Student>

    Student s1 = new Student("高圆圆"42) ;
    Student s2 = new Student("高圆圆"42) ;

/*
    HashSet集合依赖于add方法---->HashMap的put方法

    首先要比较元素的哈希码值相同----->hash()就相同
    还要比较成员信息是否相同,对应存储自定的类必须要重写Object的equals方法

    Student的这个类,必须手动给出hashCode()和equals

    Hashset集合不能保证顺序迭代恒久不变!
*/
应用场景:

在一些需求中,如果没有明确要求元素重复,那就可以使用hashSet,保证元素唯一!
类型:String,Integer,Long,…常用类都已经重写了hashCode和equals方法

TreeSet类:

集合特点:

无序性,元素唯一

底层依赖于TreeMap集合, 红黑树结构(也称为 “自平衡的二叉树结构”),可以实现Map的自然排序以及比较器排序取决于使用的构造方法

构造方法:
public TreeSet();//构造一个空的树,实现元素自然排序 (取决于存储的元素类型能否实现Comparable接口)
TreeSet能够实现两种排序:

自然排序:

TreeSet<E>();//E类型必须实现Comparable接口,实现自然排序(实现的compareTo(T t))

比较强排序:

public TreeSet(Comparator<? super E> comparator)

Comparator是一个接口类型

1)自定义一个类实现Comparator接口,重写compare方法

eg.

import com.sun.istack.internal.NotNull;

import java.util.Objects;
import java.util.TreeSet;

public class TreeSetTest01 {

    public static void main(String[] args) {

        TreeSet<Student> set = new TreeSet<>();

        set.add(new Student("laoAAAAA", 14));
        set.add(new Student("laoA", 10));
        set.add(new Student("laoAA", 11));
        set.add(new Student("laoA", 11));
        set.add(new Student("laoAAAA", 13));
        set.add(new Student("laoAA", 12));
        set.add(new Student("laoAAA", 12));


        for (Student s : set) {
            System.out.println(s.toString());
        }

    }

}

class Student implements Comparable<Student> {

    String name;
    int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                name.equals(student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    //利用接口的子实现类完成比较
    public int compareTo(@NotNull Student s) {

        int num = this.age - s.age;
        int num2 = this.name.compareTo(s.name);
        int num3 = num2 == 0 ? num : num2;
        return num3;
    }
}

2)使用接口的匿名内部类(推荐)

eg.

public class TreeSetTest02 {

    public static void main(String[] args) {

        //匿名内部类完成比较
        TreeSet<Student2> set = new TreeSet<>(new Comparator<Student2>() {
            @Override
            public int compare(Student2 s1, Student2 s2) {
                int num = s1.age - s2.age;
                int num2 = s1.name.compareTo(s2.name);
                int num3 = num2 == 0 ? num : num2;
                return num3;
            }
        });

        set.add(new Student2("laoAAAAA", 14));
        set.add(new Student2("laoA", 10));
        set.add(new Student2("laoAA", 11));
        set.add(new Student2("laoA", 11));
        set.add(new Student2("laoAAAA", 13));
        set.add(new Student2("laoAA", 12));
        set.add(new Student2("laoAAA", 12));


        for (Student2 s : set) {
            System.out.println(s.toString());
        }

    }

}


class Student2 {

    String name;
    int age;

    public Student2() {
    }

    public Student2(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student2 student = (Student2) o;
        return age == student.age &&
                name.equals(student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

}
泛型高级通配符(了解)
<?> :任意Java类型,包括Object <? super E> : 向上限定:E类型以及E父类 <? extends E>: 向下限定:E以及它的子类
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值