java-Set集合

3 篇文章 0 订阅

83.set集合的概述

-概述:一个不包含重复元素的collection,set集合的方法与collection集合的方法一样,没有特有的方法,主要研究它的子类。

-特点:无索引,不可以重复,无序(存取不一致)

package set;

import java.util.HashSet;

import Collection.Student;

public class demo2 {

	public static void main(String[] args) {
		HashSet<Student> hs = new HashSet<>();                  //当对自定义对象使用hashset时,需要重写自定义类的hascode和equals方法
		hs.add(new Student("张三",23));               
		hs.add(new Student("张三",23));
		hs.add(new Student("李四",24));
		hs.add(new Student("王五",25));
		for (Student s : hs) {
			System.out.println(s.getName()+".."+s.getAge());
		}	
	}
}

//Studnet自定义类
@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)                       //调用的对象和传入的对象是一个对象
			return true;              
		if (obj == null)                       //传入的对象不存在
			return false;
		if (getClass() != obj.getClass())       //判断两个对象的字节码文件是否是同一个字节码
			return false; 
		Student other = (Student) obj;     //向下转型
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

-Hashset原理:

  *我们使用set集合都是需要去掉重复元素的,如果在存储时候逐个equals()比较,效率较低,哈希算法提高了去重复的效率,降低了使用equals方法的次数

  *当Hashset调用add方法存储对象的时候,先调用对象的hashCode方法获得一个哈希值,然后再集合中查找是否有哈希值相同的对象

       -*如果没有哈希值相同的对象就直接存入集合。

       -*如果有哈希值相同的对象,就和哈希值相同的对象逐个进行equals比较,比较结果为false就存入,为true就不存入

-将自定义类的对象存入HashSet去重复

         *类中必须重写hashCode方法和equals方法

         *hashCode():属性相同的对象返回值必须相同,属性不同的返回值尽量不同(提高效率)

         *equals():属性相同返回true,属性不相同返回false,返回false的时候存储入集合

-LinkedHashSet的概述和特点:

-概述:链表形式的HashSet

-特点:

           *底层由链表实现,是Set集合中唯一一个能保证怎么存就怎么取的集合对象

           *因为是HashSet的子类,所以可以保证元素的唯一性

-范例1:编写一个程序,获得10个1-20的随机数,要求随机数不能重复,并打印到控制台上

 

package set;

import java.util.HashSet;
import java.util.Random;

public class demo3 {

	public static void main(String[] args) {
		//1.用Random类创建对象
		Random r = new Random();
		//2.用HashSet存储10个不能重复的随机数集合
		HashSet<Integer> hs = new HashSet<>();
		//3.利用循环添加元素
		while(hs.size() < 10){
			//添加1-20的随机数
			hs.add(r.nextInt(20)+1);
		}
		//4.foreach循环遍历
		for (Integer integer : hs) {
			System.out.println(integer);
		}
	}

}
//编写一个程序,获得10个1-20的随机数,要求随机数不能重复,并打印到控制台上

-范例2:利用Scanner从键盘读取一行输入,去掉其中重复元素,打印出不同的那些字符

package set;

import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Scanner;

public class demo4 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);         //创建Scanner对象
		while(sc.hasNext()){                    
			String s = new String(sc.nextLine());          //将键盘输入赋值给s
			char[] arr = s.toCharArray();
			LinkedHashSet<Character> hs = new LinkedHashSet<>();        //怎么存怎么取
			//HashSet<Character> hs = new HashSet<>();                             //无序输出
			for (char c : arr) {
				hs.add(c);
			}
			/*for (int i = 0; i < arr.length; i++) {
				hs.add(arr[i]);
			}*/
			for (Character c : hs) {
				System.out.print(c);
			}
		}
		/*大撒旦去我的和dsadas1232131
		    a的d旦大和我1撒2s3去*/
	}
}
/*利用Scanner从键盘读取一行输入,去掉其中重复元素,打印出不同的那些字符*/

-范例3:去除集合中重复的元素

package set;

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

public class demo5 {
/*
 * 分析:
 * 1.创建集合
 * 2.单独定义方法去重
 * 3.打印集合
 * */
	public static void main(String[] args) {
		List<String> list = new ArrayList<>();
		list.add("a");
		list.add("a");
		list.add("b");
		list.add("b");
		list.add("c");
		list.add("d");
		list.add("f");
		list.add("c");
		getSingle(list);
		System.out.println(list);
	}
/*
 * 分析:
 * 1.创建LinkedHashSet集合
 * 2.将list集合中所有的元素添加到linkedHashSet集合中
 * 3.删除原有的list集合
 * 4.将linkedHashSet中的元素添加到空的list集合中
 * */
	public  static void getSingle(List<String> list) {
		LinkedHashSet<String> lhs = new LinkedHashSet<>();
		lhs.addAll(list);             //将list集合中所有的元素添加到linkedHashSet集合中
		/*for (String s : list) {
			lhs.add(s);
		}*/
		/*list.removeAll(list);  */   
		list.clear();                     //删除集合中的所有元素
		/*for (String s : lhs) {
			list.add(s);
		}*/
		list.addAll(lhs);           //将linkedHashSet中的元素添加到空的list集合中
	}

}
//去除集合中的重复元素

84.TreeSet集合的概述和使用

-概述:TreeSet集合是用来对集合进行排序的,也可以保证元素的唯一性

-特点:TreeSet底层是通过二叉树来实现的,小的存储在左边(负数),相等的不保存(0),大的存储在右边(正数)

             *compareTo方法:在TreeSet集合如何存储元素取决于compareTo方法的返回值

             *TreeSet是用来排序的,可以指定一个顺序,对象存入之后要按照指定的顺序排序

-使用方式:

            *自然顺序(comparable):

                        *TreeSet类中的add方法会将存入的对象自动提升为comparable类型

                        *调用对象的comparable方法和集合中的对象比较

                        *根据compareTo方法返回的结果进行存储

             *比较器顺序(comparator):

                         *创建TreeSet集合的时候可以制定一个比较器(comparator)

                         *如果传入了comparator的子类对象,那么TreeSet就会按照比较器中的顺序进行排序

                         *add()方法内部会自动调用comparator接口中的compare()方法进行排序

              *两种方式的区别:

                         *TreeSet构造函数如果什么都不传,默认按照类中comparable的顺序(没有就报错ClasscastException)

                         *TreeSet如果传入comparator,就优先按照comparator

-TresSet存储自定义对象

          *需要让自定义类实现Camparable接口中的compareTo方法

          *compareTo返回0的时候集合只有一个元素

                               返回正数的时候怎么存怎么取

                               返回负数的时候倒序存储

package treeset;

import java.util.TreeSet;

import Collection.Student;

public class demo2 {

	public static void main(String[] args) {
		TreeSet<Student> ts = new TreeSet<>();
		ts.add(new Student("张三",23));
		ts.add(new Student("李四",24));
		ts.add(new Student("王五",43));
		ts.add(new Student("赵六",33));
		ts.add(new Student("周七",23));
		ts.add(new Student("张三",23));
		System.out.println(ts);
		for (Student s : ts) {
			System.out.println(s.getName()+".."+s.getAge());
		}
	}

}
student类
@Override//重写comparable接口中的方法
	/*
	 * 返回正数是怎么存怎么取
	 * 返回负数是倒序存储
	 * 返回0集合只有一个元素
	 * */
	public int compareTo(Student o) {
		int num = this.age - o.age;
		return num == 0 ? this.name.compareTo(o.name) : num;
	}

-指定比较器进行排序

 

package treeset;

import java.util.Comparator;
import java.util.TreeSet;
public class demo2 {

	public static void main(String[] args) {
		TreeSet<String> ts = new TreeSet<>(new comparetest());    //comparator c = new comparetest();  指定比较器
		ts.add("aaaaa");
		ts.add("w");
		ts.add("z");
		ts.add("nba");
		ts.add("cba");
		System.out.println(ts);
	}

}
class comparetest implements Comparator<String>{

	@Override
	public int compare(String o1, String o2) {
		int num = o1.length() - o2.length();                       //字符串长度为主要条件
		return num == 0 ? o1.compareTo(o2) : num;      //字符串内容是否相等为次要条件
	}
	
}

-范例:在一个集合中存储了无序且重复的字符串,定义一个方法,让其有序(字典顺序),而且不能去重

package treeset;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeSet;

public class demo3 {

	public static void main(String[] args) {
		ArrayList<String> list = new ArrayList<>();
		list.add("ccc");
		list.add("ccc");
		list.add("ccc");
		list.add("aaa");
		list.add("aaa");
		list.add("ccc");
		list.add("bbb");
		list.add("bbb");
		sort(list);
		System.out.println(list);
	}
/*
 * 分析:
 * 创建TreeSet集合对象,因为String本身就具备比较功能,但是重复不会保留,所以我们用比较器
 * 将List集合中的所有元素添加到TreeSet集合中,对其排序,重复保留      
 * 清空List集合
 * 将TreeSet集合中排好序的元素添加到List集合中
 * */
	public static void sort(ArrayList<String> list) {
		TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {         //匿名内部类

			@Override       //重写comparator接口的方法
			public int compare(String o1, String o2) {
				int num = o1.compareTo(o2);
				return num == 0 ? 1 : num ;            //当两个字符串相同时,使其保留
			}
		});
		ts.addAll(list);               //将list集合中的元素复制到TreeSet集合中
		list.clear();
		list.addAll(ts);
	}

}
/*
 *在一个集合中存储了无序且重复的字符串,定义一个方法,让其有序(字典顺序),而且不能去重 
 *
 */

-范例:从键盘接口一个字符串,程序对其中所有字符串进行排序,例如输入:helloitcast 输出 acehillostt

package treeset;

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
/*
 * 分析:
 * 先将字符串转换为字符数组
 * 创建一个character类型的TreeSet集合,并定义比较器,使其重复元素保留
 * 将arr中的元素添加到TreeSet集合中
 * 打印TreeSet集合
 * */
public class demo4 {

	public static void main(String[] args) {
		Scanner sc  = new Scanner(System.in);
		while(sc.hasNext()){
			String s = new String(sc.nextLine());
			char[] arr = s.toCharArray();
			TreeSet<Character> ts = new TreeSet<>(new Comparator<Character>() {

				@Override
				public int compare(Character o1, Character o2) {        //若o1等于o2,则保留
					int num = o1.compareTo(o2);
					return num == 0 ? 1 : num;
				}
			});
			for (Character c : arr) {       //遍历arr,将arr数组中的元素添加到ts集合中
				ts.add(c);
			}
			for (Character c : ts) {
				System.out.print(c);
			}
		}
	}

}
//从键盘接口一个字符串,程序对其中所有字符串进行排序,例如输入:helloitcast 输出 acehillostt

-范例:程序启动后,从键盘输入接收多个整数,直到输入quit结束输入,把所有输入的整数倒序排列打印

package treeset;

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;
/*
 * 分析:
 * 1.创建scanner对象,键盘录入
 * 2.创建TreeSet集合对象,TreeSet集合中传入比较器
 * 3.无限循环不断接收整数,遇到quit退出循环,因为quit时字符串,所以键盘录入的形式都应该是字符串
 * 4.判断是否是quit,是就退出,不是就将其转换为integer类型,并将其添加到TreeSet集合中
 * 5.打印TreeSet集合
 * */
public class demo5 {
	public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    TreeSet<Integer> ts = new TreeSet<>(new Comparator<Integer>() {          //创建TreeSet集合
		@Override
		public int compare(Integer o1, Integer o2) {        //设置比较器,使其倒叙输出,且重复元素保留
			int num  = o2 - o1;   //自动拆箱
			return num == 0 ? 1 : num;
		}
	});
    while(true){                        						//设置无限循环,不断接收整数
    	String line = sc.nextLine();  
    	if("quit".equals(line)){                       	//当输入quit时退出循环
    		break;
    	}else{
    		Integer i = new Integer(line);        //将String转换为integer
    		ts.add(i);                                               //将integer对象添加到集合中
    	}
    }
    for (Integer i : ts) {
		System.out.println(i);
	}
	}
}
//程序启动后,从键盘输入接收多个整数,直到输入quit结束输入,把所有输入的整数倒序排列打印

-范例:键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台

package treeset;

import java.util.Scanner;
import java.util.TreeSet;
/*
 * 分析:
 * 1.定义一个学生类:
 *            成员变量:姓名,语文成绩,数学成绩,英语成绩
 *            成员方法:空参,有参构造的参数为姓名,语文成绩,数学成绩,英语成绩
 *            toString方法,在遍历集合中的Student对象打印对象引用的时候显示属性值
 *2.键盘录入创建Scanner对象
 *3.创建TreeSet集合对象,在TreeSet的构造函数传入比较器,按照总分比较
 *4.录入5个学生,以集合中的学生个数为判断条件,如果size小于5就进行存储
 *5.将录入的字符串进行切割,用逗号来进行切割,返回一个字符数组,将数组从第二位元素开始到末尾的元素转换为int类型
 *6.将转换后的结果封装为student对象,并添加到TreeSet集合中
 *7.打印TreeSet集合
 * */
public class demo6 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);                      //创建键盘录入对象
		TreeSet<Student> ts = new TreeSet<>();                  //创建TreeSet集合
		System.out.println("请输入成绩,格式为:姓名,语文成绩,数学成绩,英语成绩");
		while(ts.size()<5){
			String line = sc.nextLine();       
			String[] arr = line.split(",");                                   //将字符串切割为字符数组
			int CS = Integer.parseInt(arr[1]);
			int MS = Integer.parseInt(arr[2]);
			int ES = Integer.parseInt(arr[3]);
			ts.add(new Student(arr[0],CS,MS,ES));               //将转换后的结果封装为student对象
		}
		for (Student student : ts) {
			System.out.println(student);
		}
	}

}
class Student implements Comparable<Student>{         //让自定义类实现comparable接口,也可以实现比较
	private String name;
	private int CS;        //语文成绩
	private int MS;   	//数学成绩
	private int ES; 		//英语成绩
	private int sum;
	
	
	public int getSum() {
		return sum;
	}

	public Student(String name, int cS, int mS, int eS) {
		super();
		this.name = name;
		CS = cS;
		MS = mS;
		ES = eS;
		this.sum = this.CS + this.MS + this.ES ;
	}

	public Student() {
		super();
	}

	@Override   
	public int compareTo(Student o) {
		int num = (o.CS+o.MS+o.ES) - (this.CS+this.MS+this.ES);
		return num == 0 ? 1 : num;
	}

	@Override     //重写toString方法
	public String toString() {
		return name+","+CS+","+MS+","+ES+","+sum;
	}
	
}
//键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顾十方

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值