Java基础系列30-单列 Collection集合

x33g5p2x  于2021-12-18 转载在 其他  
字(18.3k)|赞(0)|评价(0)|浏览(432)

一.集合的概述

集合是一个容器,是用来存储和获取数据;

集合类的特点长度可变;

1.1 为什么会出现集合类

我们学习的是面向对象的编程语言,面向对象的编程语言对事物的描述都是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储,而要想存储多个对象,就不能是基本的变量了,应该是一个容器类型的变量。回顾我们学过的知识,有哪些是容器类型的呢?

数组,StringBuilder,它的结果是一个字符串,不一定满足我们的需求,所以我们只能选择数组了,而数组的长度固定,不能适应变化的需求,在这种情况下,Java就提供了集合类供我们使用。

由此可见,集合类的长度是可变的。

1.2 集合类体系结构图

二.Collection集合

2.1 Collection集合入门

Collection是单列集合的顶层接口。

元素Collection 表示一组对象,这些对象也称为 collection 的

特点:

  1. 一些 collection 允许有重复的元素,而另一些则不允许。
  2. 一些 collection 是有序的,而另一些则是无序的。
  3. JDK 不提供此接口的任何直接 实现:它提供更具体的子接口(如 Set 和 List)实现。

ArrayList()是创建Collection集合的对象,我们采用的是多态的方式,使用的是具体的ArrayList类。因为这个类是最常用的集合类。

Collection:是一种特殊的数据类型,泛型。这里我们会使用就可以了。如何使用呢?

  1. 在出现E的地方用引用数据类型替换即可。
  2. 举例:Collection,Collection

代码:

package Java_study;

import java.util.ArrayList;
import java.util.Collection;

/**
 * 
 * @author  只是甲
 * @date    2021-07-02
 * @remark  创建Collection集合对象并添加元素
 *
 */
public class collection1 {
	public static void main(String[] args) {
		//创建Collection集合对象
        //下面这种写法是JDK7的新特性,看懂就可以,但不建议这种写法,最好还是补全<>中的类型
        //Collection<String> c = new ArrayList<>(); //多态的方式
		Collection<String> c = new ArrayList<>();
		c.add("hello");
		c.add("world");
		c.add("java");
		
		//输出集合对象
        //输出了集合中的元素按照指定格式拼接的内容,说明ArrayList重写了toString()方法
        /* [hello, world, java] */
		System.out.println(c);
		
	}

}

测试记录:

[hello, world, java]

2.2 Collection集合的成员方法

//添加元素
boolean add(E e);
//从集合中移除元素
boolean remove(Object o);
//清空集合中的元素
void clear();
//判断集合中是否存在指定的元素
boolean contains(Object o);
//判断集合是否为空
boolean isEmpty();
//集合的长度,也就是集合中元素的个数
int size();

代码:

package Java_study;

import java.util.Collection;
import java.util.ArrayList;

/**
 * 
 * @author  只是甲
 * @date    2021-07-02
 * @remark  Collection集合的成员方法
 *
 */
public class collection2 {
	public static void main(String[] args) {
		//创建集合对象
		Collection<String> c = new ArrayList<>();
		
		//1.添加元素
		System.out.println("add:" + c.add("hello"));
		System.out.println("add:" + c.add("world"));
		
		System.out.println("----1------");
		
		//2.从集合中删除元素
		System.out.println("remove:" + c.remove("world"));
		System.out.println("remove:" + c.remove("haha"));
		
		System.out.println("-----2-----");
		
		//3.清空集合
		System.out.println(c);
		c.clear();
		System.out.println(c);
		
		System.out.println("-----3-----");
		
		//4.判断集合中是否存在指定的元素
		c.add("world");
		System.out.println("contains:" + c.contains("world"));
		System.out.println("contains:" + c.contains("haha"));
		
		System.out.println("-----4-----");
		
		//5. 判断集合是否为空
		System.out.println("isEmpty:" + c.isEmpty());
		System.out.println("-----5-----");
		
		//6. 集合的长度
		System.out.println("size:" + c.size());
		System.out.println("----6------");
		
		//输出集合对象
		System.out.println(c);
		
		
		
	}

}

测试记录:

add:true
add:true
----1------
remove:true
remove:false
-----2-----
[hello]
[]
-----3-----
contains:false
contains:false
-----4-----
isEmpty:false
-----5-----
size:1
----6------
[world]

2.3 Collection集合的遍历

Collection集合的遍历:

  1. Iterator iterator() : 返回在此 collection 的元素上进行迭代的迭代器;
  2. 通过集合对象调用iterator()方法得到迭代器对象;

Iterator:

  1. E next():返回迭代的下一个元素;
  2. boolean hasNext():如果仍有元素可以迭代,则返回 true;

代码:

package Java_study;

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

/**
 * 
 * @author  只是甲
 * @date    2021-07-02
 * @remark  Collection集合的遍历 
 *
 */
public class collection3 {
	public static void main(String[] args) {
		//创建集合对象
		Collection<String> c1 = new ArrayList<String>();
		
		//添加元素
		c1.add(new String("hello"));
		c1.add("world");
		c1.add("java");
		
		//Iterator<E> iterator()
		Iterator<String> it1 = c1.iterator();//返回的是跌抬起接口的实现类的对象
		
		try {
			System.out.println(it1.next());//hello
			System.out.println(it1.next());//world
			System.out.println(it1.next());//java
			System.out.println(it1.next());//NoSuchElementException:没有这样的元素异常
		} catch (NoSuchElementException e) {
			System.out.println("NoSuchElementException:没有这样的元素异常");
		}
		
		/* 遍历方式一:iterator.hasNext()
        boolean hasNext 如果还有下一个元素则返回true 否则跳出循环,避免NoSuchElementException
        */
		System.out.println("===========方式一:iterator.hasNext()===============");
		Iterator<String> it2 = c1.iterator();
		while (it2.hasNext()) {
			String s = it2.next();
			System.out.println(s);
		}
		
		/* 遍历方式二: try catch 获取NoSuchElementException异常 */
        System.out.println("===========方式二:try catch===============");
        Iterator<String> it3 = c1.iterator();
        iter:
        	while (true) {
        		try {
        			System.out.println(it3.next());
        		} catch (NoSuchElementException e) {
        			System.out.println("遍历结束");
        			break iter;
        		}
        	}
        
        /* 遍历方式三: 增强for循环 c1.for根据提示自动生成*/
        System.out.println("===========方式三:增强for循环===============");
        for (String s : c1) {
        	System.out.println(s);
        }
	}

}

测试记录:

hello
world
java
NoSuchElementException:没有这样的元素异常
===========方式一:iterator.hasNext()===============
hello
world
java
===========方式二:try catch===============
hello
world
java
遍历结束
===========方式三:增强for循环===============
hello
world
java

2.4 集合使用步骤图解

三. List集合

3.1 List集合特点

List:

  1. 有序的 collection(也称为序列);
  2. 此接口的用户可以对列表中每个元素的插入位置进行精确地控制;
  3. 用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素;
  4. 与 set 不同,列表通常允许重复的元素;

List集合的特点:

  1. 有序(存储和取出元素的顺序一致);
  2. 存储的元素可以重复;

代码:

package Java_study;

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

/**
 * 
 * @author  只是甲
 * @date    2021-07-02
 * @remark  List集合的特点
 *
 */
public class list1 {
	public static void main(String[] args) {
		//创建集合对象
		List<String> list = new ArrayList<String>();
		
		//存储元素
		list.add("hello");
		list.add("world");
		list.add("java");
		
		//遍历集合
		Iterator<String> it = list.iterator();
		while (it.hasNext()) {
			String s = it.next();
			System.out.println(s);
		}
	}

}

测试记录:

hello
world
java

3.2 List集合的特有成员方法

//在指定位置添加元素
void add(int index,E element);
//删除指定位置的元素
E remove(int index);
//获取指定位置的元素
E get(int index);
//修改指定位置的元素
E set(int index,E element);

代码:

package Java_study;

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

/**
 * 
 * @author 只是甲
 * @date   2021-04-19
 * @remark List集合的特有成员方法
 *
 */
public class list2 {
	public static void main(String[] args) {
		//创建集合对象
		List<String> list = new ArrayList<String>();
		
		//使用集成Collection的添加功能
		list.add("hello");
		list.add("world");
		list.add("java");
	
	
	    // 1. void add(int index,E element):在指定位置添加元素
        System.out.println("==========1. void add(int index,E element):在指定位置添加元素==========");
    
        try {
    	    list.add(1, "javaee");
    	    list.add(11, "javase");//IndexOutOfBoundsException,索引超出边界异常,list中没有这个数据
        } catch (IndexOutOfBoundsException e) {
    	    System.out.println("IndexOutOfBoundsException,索引超出边界异常,list中没有这个数据");
        }
        System.out.println(list);//[hello, javaee, world, java]
        
        //2. E remove(int index):删除指定位置的元素,返回被删除的元素
        System.out.println("==========2. E remove(int index):删除指定位置的元素,返回被删除的元素==========");
        try {
        	System.out.println("remove: " + list.remove(2));
        	System.out.println("remove: " + list.remove(11));//IndexOutOfBoundsException,索引超出边界异常,list中没有这个数据
        } catch (IndexOutOfBoundsException e) {
        	System.out.println("IndexOutOfBoundsException,索引超出边界异常,list中没有这个数据");
        }
        System.out.println(list);//[hello, javaee, java]
        
        //3.  E get(int index):获取指定位置的元素
        System.out.println("==========3.  E get(int index):获取指定位置的元素==========");
        try {
        	System.out.println("get:" + list.get(1));
        	System.out.println("get:" + list.get(11));//IndexOutOfBoundsException,索引超出边界异常,list中没有这个数据
        } catch (IndexOutOfBoundsException e) {
            System.out.println("IndexOutOfBoundsException,索引超出边界异常,list中没有这个数据");
        }
        
   
    
	}

}

测试记录:

==========1. void add(int index,E element):在指定位置添加元素==========
IndexOutOfBoundsException,索引超出边界异常,list中没有这个数据
[hello, javaee, world, java]
==========2. E remove(int index):删除指定位置的元素,返回被删除的元素==========
remove: world
IndexOutOfBoundsException,索引超出边界异常,list中没有这个数据
[hello, javaee, java]
==========3.  E get(int index):获取指定位置的元素==========
get:javaee
IndexOutOfBoundsException,索引超出边界异常,list中没有这个数据

3.3 List集合的普通for循环遍历

List集合的遍历方式:

  1. 迭代器
  2. 普通for循环
  3. 增强for循环

代码:

package Java_study;

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

/**
 * 
 * @author  只是甲
 * @date    2021-07-02
 * @remark  List集合的普通for循环遍历
 *
 */
public class list3 {
	public static void main(String[] args) {
		//创建集合对象
		List<String> list = new ArrayList<String>();
		
		//添加循环
		list.add("hello");
		list.add("world");
		list.add("java");
		
		// E get(int index):获取指定位置的元素
		try {
			System.out.println(list.get(0));
			System.out.println(list.get(1));
			System.out.println(list.get(2));
			System.out.println(list.get(3));//IndexOutOfBoundsException,索引超出边界异常,list中没有这个数据
		} catch (IndexOutOfBoundsException e) {
			System.out.println("IndexOutOfBoundsException,索引超出边界异常,list中没有这个数据");
		}
	}

}

测试记录:

hello
world
java
IndexOutOfBoundsException,索引超出边界异常,list中没有这个数据

3.4 List集合练习

自定义一个学生类,给出成员变量name和age。
遍历集合的时候,在控制台输出学生对象的成员变量值。

两种方式遍历:

  1. 迭代器
  2. 普通for
  3. 增强for

代码:
list4

package Java_study;

/**
 * 
 * @author  只是甲
 * @date    2021-07-05
 * @remark  实体学生类 List集合的练习存储自定义对象并遍历
 *
 */
public class list4 {
	private String name;
	private int age;
	
	public list4(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;
	}
	
	/**
     * @remark 重写Object类的toString方法
     * @return 学生类的姓名,年龄信息
     */
	@Override
    public String toString() {
		return "Student{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
	}

}

list5

package Java_study;

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

/**
 * 
 * @author  只是甲
 * @date    2021-07-05
 * @remark  测试类 List集合的练习存储自定义对象并遍历
 *
 */
public class list5 {
	public static void main(String[] args) {
		//创建集合对象
		List<list4> list = new ArrayList<list4>();
		
		//创建元素对象
		list4 s1 = new list4("杜兰特",33);
		list4 s2 = new list4("库里",33);
		list4 s3 = new list4("詹姆斯",37);
		
		//把元素添加到集合
		list.add(s1);
		list.add(s2);
		list.add(s3);
		
		// a.迭代器
		System.out.println("=====a.迭代器=====");
		Iterator<list4> it = list.iterator();
		while (it.hasNext()) {
			list4 s = it.next();
			System.out.println(s.toString());
		}
		
		//b.普通for
		System.out.println("=====b.普通for=====");
		for (int i = 0; i < list.size(); i++) {
			list4 s = list.get(i);
			System.out.println(s.toString());
		}
		
		//c.增强for
		System.out.println("=====c.增强for=====");
		for (list4 s : list) {
			System.out.println(s.toString());
		}
		
	}

}

测试记录:

=====a.迭代器=====
Student{name='杜兰特', age=33}
Student{name='库里', age=33}
Student{name='詹姆斯', age=37}
=====b.普通for=====
Student{name='杜兰特', age=33}
Student{name='库里', age=33}
Student{name='詹姆斯', age=37}
=====c.增强for=====
Student{name='杜兰特', age=33}
Student{name='库里', age=33}
Student{name='詹姆斯', age=37}

3.5 List.ListIterator();

ListIterator:

  1. ListIterator listIterator():返回此列表元素的列表迭代器
  2. public interface ListIteratorextends Iterator

特有功能:

  1. E previous():返回列表中的前一个元素。
  2. boolean hasPrevious():如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。

注意:

  1. ListIterator可以实现逆向遍历,但是要求先正向遍历,才能逆向遍历。

代码:

package Java_study;

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

/**
 * 
 * @author 只是甲
 * @date   2021-07-05
 * @remark  列表迭代器的特有功能ListIterator
 *
 */
public class list6 {
	public static void main(String[] args) {
		//创建集合对象
		List<String> list = new ArrayList<String>();
		
		//添加元素
		list.add("hello");
		list.add("world");
		list.add("java");
		ListIterator<String> lit = list.listIterator();
		
		System.out.println("=====a.直接逆向遍历list数组=====");
		while (lit.hasPrevious()) {
			String s = lit.previous();
			System.out.println(s);
		}
		System.out.println("=====b.先正向遍历list数组再逆向遍历list数组=====");
		while (lit.hasNext()) {
			String s = lit.next();
		}
		while (lit.hasPrevious()) {
			String s = lit.previous();
			System.out.println(s);
		}
	}

}

测试记录:

=====a.直接逆向遍历list数组=====
=====b.先正向遍历list数组再逆向遍历list数组=====
java
world
hello

3.6 List并发修改异常

需求:

  1. 有一个集合List list = new ArrayList();
  2. 里面有三个元素list.add(“hello”);list.add(“world”);list.add(“java”);
  3. 我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。

ConcurrentModificationException:

  1. 当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。

产生的原因:

  1. 迭代器依赖于集合而存在,在判断成功后,集合中添加了新的元素,而迭代器并不知道,所有就报错了。
  2. 其实这个问题说的是:迭代器遍历集合中的元素的时候,不要使用集合对象去修改集合中的元素。

如何解决?
A : 迭代器遍历的时候,我可以通过迭代器修改集合中的元素
元素是跟在刚才迭代的元素后面的
B : 集合遍历的时候,我可以通过集合对象修改集合中的元素
元素是在最后添加的

代码:

package Java_study;

import java.util.*;

/**
 * 
 * @author  并发修改异常产生的原因及解决方案只是甲
 * @date    2021-07-05
 * @remark 
 *
 */
public class list7 {
	public static void main(String[] args) {
		// 创建集合对象
		List<String> list = new ArrayList<String>();
		
		// 添加元素
		list.add("hello");
		list.add("world");
		list.add("java");
		System.out.println(list);
		
		//我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素
		Iterator<String> it = list.iterator();
		
		//ConcurrentModificationException:添加失败,当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
		/*while (it.hasNext()) {
			String s = it.next();
			if (s.equals("world")) {
				list.add("javaee");
			}
			System.out.println(s);
		}*/
		
		
		//A:迭代器遍历的时候,我可以通过迭代器修改集合中的元素(元素是跟在刚才迭代的元素后面的)
		ListIterator<String> lit = list.listIterator();
		while (lit.hasNext()) {
			String s = lit.next();
			if (s.equals("world")) {
				lit.add("javaee");
			}
		}
		System.out.println(list);
		
		//B:集合遍历的时候,我可以通过集合对象修改集合中的元素(元素是在最后添加的)
		for (int x = 0; x < list.size(); x++) {
			String s = list.get(x);
			if (s.equals("world")) {
				list.add("javaee");
			}
		}
		System.out.println(list);
	}

}

测试记录:

[hello, world, java]
[hello, world, javaee, java]
[hello, world, javaee, java, javaee]

四.数据结构

什么是数据结构?
  数据的组织方式;

4.1 常见数据结构【栈】【队列】

栈 :FIFO(First In First Out) 先进先出
队列 :FILO(First In Last Out) 先进后出

4.2 常见数据结构【数组】【链表】

数组 :存储同一种数据类型的多个元素的容器,有索引,方便我们获取元素;
  应用 : ArrayList ;

链表 :由一个链子把多个节点连接起来的数据;
  结点 :由 数据 和 下一个元素的地址 组成;
  应用 : LinkedList ;

五. ArrayList案例

5.1 ArrayList集合存储字符串

List
  ArrayList : 底层数据结构是数组,查询快,增删慢
  LinkedList : 底层数据结构是链表,查询慢,增删快

ArrayList存储字符串并遍历
  A : 迭代器
  B : 普通for
  C : 增强for

代码:

package Java_study;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * 
 * @author  只是甲
 * @date    2021-07-05
 * @remark  ArrayList集合存储字符串
 *
 */
public class arraylist1 {
	public static void main(String[] args) {
		//创建集合对象
		ArrayList<String> arr = new ArrayList<String>();
		
		//添加元素
		arr.add("hello");
		arr.add("world");
		arr.add("java");
		
		//a.迭代器 arr.iterator
		System.out.println("a.迭代器 arr.iterator");
		Iterator<String> it = arr.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
		}
		
		//b.普通for arr.fori
		System.out.println("b.普通for arr.fori ");
		for (int i = 0; i < arr.size(); i++) {
			System.out.println(arr.get(i));
		}
		
		//c.增强for
		for (String s: arr) {
			System.out.println(s);
		}
		
	}

}

测试记录:

a.迭代器 arr.iterator
hello
world
java
b.普通for arr.fori 
hello
world
java
hello
world
java

六.Set集合特点和HashSet集合类

Collection接口 – List(接口,可重复,存取顺序一致) 、 Set(接口,唯一,存取顺序不一致)
  List接口 – ArrayList(实现类,数据结构为数组)、LinkedList(实现类,数据结构为链表)
  Set接口 – HashSet(实现类)

Set
  元素唯一,存储元素无序 ;
  一个不包含重复元素的 collection;

HashSet
  它不保证 set 的迭代顺序,特别是它不保证该顺序恒久不变;

代码:

package Java_study;

import java.util.HashSet;
import java.util.Set;

/**
 * 
 * @author  只是甲
 * @date    2021-07-05
 * @remark  Set集合的特点
 *
 */
public class set1 {
	public static void main(String[] args) {
		//创建集合对象
		Set<String> set = new HashSet<>();
		
		//添加元素
		set.add("hello");
		set.add("world");
		set.add("java");
		
		//set集合的唯一性: 再次添加相同的元素,但集合该元素唯一
		set.add("world");
		
		//遍历集合 set.for 
		for (String s : set) {
			System.out.println(s);
		}
	}

}

测试记录:

world
java
hello

6.2 HashSet集合类

HashSet它不保证 set 的迭代顺序,特别是它不保证该顺序恒久不变;

6.2.1 HashSet元素唯一性原理

HashSet保证元素唯一性的原理?
  通过查看add方法的源码,我们知道了添加功能的执行过程中,是进行了数据的判断的。
  这个判断的流程是:
    首先比较对象的哈希值是否相同,这个哈希值是根据对象的hashCode()计算出来的。
    如果哈希值不同,就直接添加到集合中
    如果哈希值相同,继续执行equals()进行比较,
      返回的是true,说明元素重复,不添加。
      返回的是false,说明元素不重复,就添加。
  如果我们使用HashSet集合存储对象,你要想保证元素的唯一性,就必须重写hashCode()和equals()方法。

代码:

package Java_study;

import java.util.HashSet;

/**
 * 
 * @author 只是甲
 * @date   2021-07-05
 * @remark HashSet保证元素唯一性的原理
 *
 */
public class hashset1 {
	public static void main(String[] args) {
		//创建集合对象
		HashSet<String> hs = new HashSet<>();
		
		//添加元素
		hs.add("hello");
		hs.add("world");
		hs.add("java");
		
		//set集合的唯一性:  再次添加相同元素,但集合内该元素只有一个
		hs.add("world");
		
		//遍历集合
		for (String h : hs) {
			System.out.println(h);
		}
	}

}

测试记录:

world
java
hello

6.2.2 HashSet集合存储实体类

需求
  自定义一个学生类,给出成员变量name和age。
  遍历集合的时候,在控制台输出学生对象的成员变量值。

遍历方式
  a.迭代器
  b.增强for

代码:
hashset2

package Java_study;

/**
 * 
 * @author  只是甲
 * @date    2021-07-05
 * @remark  实体学生类 HashSet集合存储实体类
 *
 */
public class hashset2 {
	private String name;
	private int age;
	
	public hashset2(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 "{name='" + name + "'" + ", age=" + age + '}';
	}

}

hashset3

package Java_study;

import java.util.HashSet;
import java.util.Iterator;

/**
 * 
 * @author  只是甲
 * @date    2021-07-05
 * @remark  测试类 HashSet集合存储实体类
 *
 */

public class hashset3 {
	public static void main(String[] args) {
		//创建集合对象
		HashSet<hashset2> hs = new HashSet<>();
		
		//创建元素对象
		hashset2 s1 = new hashset2("杜兰特",33);
		hashset2 s2 = new hashset2("库里",33);
		hashset2 s3 = new hashset2("詹姆斯",37);
		
		//把元素添加到集合
		hs.add(s1);
		hs.add(s2);
		hs.add(s3);
		
		//a.迭代器遍历 hs.iterator()
		Iterator<hashset2> it = hs.iterator();
		System.out.println("a.迭代器遍历 hs.iterator()");
		while (it.hasNext()) {
			hashset2 s = it.next();
			System.out.println(s.toString());
		}
		
		//b.增强for遍历 it.next()
		System.out.println("b.增强for遍历 it.next()");
		for (hashset2 s:hs) {
			System.out.println(s);
		}
		
	}

}

测试记录:

a.迭代器遍历 hs.iterator()
{name='詹姆斯', age=37}
{name='杜兰特', age=33}
{name='库里', age=33}
b.增强for遍历 it.next()
{name='詹姆斯', age=37}
{name='杜兰特', age=33}
{name='库里', age=33}

6.2.3 HashSet重写hashCode();equals();

要求
  如果对象的成员变量值相同,就认为是同一个元素。

提示
  自定义一个学生类,给出成员变量name和age。遍历集合的时候,在控制台输出学生对象的成员变量值。

遍历方式
  a.迭代器
  b.增强for

因为我们存储的元素所属的类没有重写hashCode()和equals()方法,所以保证不了元素的唯一性。
  而我想保证,怎么办呢?重写这两个方法就可以了。
  如何重写呢?自动生成就可以了。

代码:
hashset4

package Java_study;

import java.util.Objects;

/**
 * 
 * @author  只是甲
 * @date    2021-07-06
 * @remark  实体学生类 HashSet重写hashCode();equals();
 *
 */

public class hashset4 {
	private String name;
	private int age;
	
	public hashset4(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 "{name='" + name + "'" + ", age=" + age + '}';
	}
	
	/**
     * @remark 因为我们存储的元素所属的类没有重写hashCode()和equals()方法,所以保证不了元素的唯一性。
     *              而我想保证,怎么办呢?重写这两个方法就可以了。
     *              如何重写呢?自动生成就可以了。alt+insert
     * @param o
     * @return
     */
	@Override
	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;
		hashset4 that = (hashset4) o;
		return age == that.age && name.equals(that.name);
	}
	
	/**
     * @remark 因为我们存储的元素所属的类没有重写hashCode()和equals()方法,所以保证不了元素的唯一性。
     *          而我想保证,怎么办呢?重写这两个方法就可以了。
     *          如何重写呢?自动生成就可以了。alt+insert
     * @return
     */
    @Override
    public int hashCode() {
    	return Objects.hash(name, age);
    }

	

}

hashset5

package Java_study;

import java.util.HashSet;

/**
 * 
 * @author  只是甲
 * @date     2021-07-06
 * @remark   测试类 HashSet重写hashCode();equals();
 *
 */

public class hashset5 {
	public static void main(String[] args) {
		HashSet<hashset4> hs = new HashSet<>();
		
		hashset4 s1 = new hashset4("杜兰特",33);
		hashset4 s2 = new hashset4("库里",33);
		hashset4 s3 = new hashset4("詹姆斯",38);
		hashset4 s4 = new hashset4("东契奇",22);
		
		//把元素添加到集合
		hs.add(s1);
		hs.add(s2);
		hs.add(s3);
		hs.add(s4);
		
		//增强for遍历集合 hs.for
		for (hashset4 h:hs) {
			System.out.println(h);
		}
	}

}

测试记录:

{name='杜兰特', age=33}
{name='詹姆斯', age=38}
{name='库里', age=33}
{name='东契奇', age=22}

参考:

  1. https://blog.csdn.net/qq_43529621/article/details/115954338

相关文章