Java面向对象第十天(--Set集合--)

1.set集合

 特点:无序(没有下标) 不重复

 子类:  HashSet : 去重的功能; LinkedHashSet:表示的是有序的;

          TreeSet:  有自己独特的方法:排序的功能

1.1关于HashSet去重的问题:

 HashSet 在存放对象的时候会判断对象是不是同一个对象 .

1.  默认引用类型比较的是地址值,如果地址相同,name这是一模一样的对象,将不再重复往里面放.

2 . 如果对象 重写了hashcode和equals放法,就比较这两者是否相等.

如果hashcode相等,那么比较的是equals方法,如果equals再相等,那么证明这是同一个对象,如果equals不相等,

那么即使hashcode相等,也是两个对象.

3.HashSet已经重写了父类的equals和hashcode方法;

注意:equals和 == 区别!

简单的说,“==”用于判断引用是否相等,equals()用于判断值是否相等
public static void main(String[] args) {
        
        String a = new String("abc");
        String b = new String("abc");

        System.out.println(a==b);//结果为false
        System.out.println(a.equals(b));//结果为true
}

例题:1.  创建一个HashSet  2. 保存  f f  a a b  b;(在系统类中操作去重)

只要创建对象,就会给没一个对象分配一个hashcode;   hashcode 如果不同就不会调用equals .

HashSet<String>hash = new HashSet();
hash.add("f");
hash.add("f");
hash.add("a");
hash.add("a");
hash.add("b");
hash.add("b");
//迭代器遍历
  Interator iterator=hash.iterator();
  while(iterator.hasNext()){
     String next = iterator.next();
     System.out.println(next);
 //或者增强for 循环进行遍历
    for (String string : hash){
       System.out.println(string); 
 } 
}

2 : HashSet如何在自己创建的类中去重

            1. 自己创建一个Person类;创建一个集合保存6个Person;并且要去去重.

HashSet<Person> set = new HashSet<>();
 set.add(new Person("张三"),12);
 set.add(new Person("张三"),12);
 set.add(new Person("张四"),13);
 set.add(new Person("张四"),13);
 set.add(new Person("张五"),14);
 set.add(new Person("张五"),14);
//遍历集合 
 for(Person person:set){
   System.out.println(set)

 }
//想要获得的打印结果,需要重写Person的hashCode 和equals方法;
Person [name=张三, age=12]
Person [name=张四, age=13]
Person [name=张五, age=14]


     2.创建一个Person类;

public class Person  implements Comparable<Person>{//这里实现comparable是为了下面用TreeSet排序; 在下面3中例题3里面有体现;
 private String name ;
 private int 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 + "]";
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public Person() {
		super();
		
	}
 
//因为上面创建的集合要进行除重操作,这时父类的去重方法不再适用(父类==比较的是地址),我们需要重写hashCode和equals方法;
         public int hashCode(){
//这里如果过返回值是一样的,默认两个对象是一样的;这里返回值我们和两个成员变量进行联系
               return this.name.hashCode() + this.age;
}
//重写equals方法
           public boolean equals (Object object){
                 Person p = (Person) object;
//如果字符串(name) 一样并且年龄的数值一样,那么这两个对象就是一样的这样我们就可以进去重了;
                 return this.name.equals(p.name)&&this.getAge==p.getAge()
     } 
}
 
 
public int compareTo(Person o) {  //此处重写了接口compareble中的 compareTo方法;
		// TODO Auto-generated method stub
		 //按照年龄排序,如果是int 直接相减;
		//return (this.age) - (o.getAge());
		//按照姓名比较需要使用字符串compare"To进行比较 返回int值点进去看;
		//return this.name.compareTo(o.getName());
		int num = this.age -o.getAge();
		//这时啥意思;
		return num==0?this.name.compareTo(o.getName()):num;
		     
	}


3.利用set集合 去除ArrayList集合的重复元素; ArraysList里面保存着 a a b b c c d d ;

ArrayList<String> list = new ArrayList();
list.add("a")
list.add("a")
list.add("b")
list.add("b")
list.add("c")
list.add("c")
//创建HashSet集合接收一下,顺便去重
HashSet<String> set = new HashSet();
set.addAll(list); //将list集合里面的元素全部放到set里面去
list.clear();     //清空list
list.addAll(set); //再将处理好的数据放回到list 里面;
//增强for循环;遍历
for(String string: list)
 

4.编写一个程序,获取10个 1 -20的随机数,要去随机数不能重复 1.创建一个set 2. 循环生成10个数 3. 添加到set中去;

HashSet<Integer> set = new Integer();
 while(set.size()<10){
        int rd = (int)(Math.random()*(20-1+1)+1);
     //循环往集合里面添加数据;
      set.add(rd);//这里系统自动装箱,可一直接传入int类型的数字;

}
//打印集合长度
System.out.println(Hash.size());
打印这个集合;
System.out.println(set);

3 TreeSet是如何进行排序的:

 TreeSet支持两种排序方法:自然排序和定制排序。TreeSet默认采用自然排序。

 TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间大小关系.然后将集合元素按升序排列,这种方式就是自然排序。(比较的前提:两个对象的类型相同)。

    1.主要有两种方式

                  方式1:   1. Object实现comparable接口,可以重写compareTo方法;   2. 实现接口中的compareTo()方法; 3. 编写你想要的排序规则;(自己创建的类)在类里面

                  方式2:    1. 系统类 : (comparator)比较器. 1 创建比较器, 在创建一个是实现接口的实现类,重写compare()方法再将

                   实现类创建的一个对象,放入到 new TreeSet(  new 对象);

 两种重写方法返回值都是 int 类型;

     1 . 创建一个TreeSet集合添加几个数,查看是如何排序的;(Integer比较的是数值的大小)

TreeSet(Integer)set = new TreeSet();
set.add(6);
    	       set.add(3);
    	       set.add(3);
    	       set.add(7);
set.add(5); System.out.println(set);//打印结果 [3, 5, 6, 7] //去重并且排序了;

 2. 例题:  创建一个TreeSet集合,集合中保存的是字符串,按照字符串的长度进行排序,(这里使用的是系统类;)

 这里我们需要重写比较规则,需要创建一个比较器(comparator),然后找个实现比较器的类,最后在初始化TreeSet对象的时候

将该实现类传进去;

  2 : 创建一个类实现(接口comparator)中的Compara()方法;

public class StringLengthImpl implements 
Comparator <String>{
  //实现比较器中的方法;
public int compare(String o1,String o2){
  //如果两个字符串长度不一样.直接返length;
      //字符串长度进行对比;返回值length
  int length = o2.length- o1.length;
     //如果长度相等要比较每一位了;
   int num1= o2.compareT(o1);
   //用判断语句接收上面返回的结果
   int rel = length==0?num1:length;
    //最终判断,就算相等也不能赋值0.0会默认去重;
    return rel == 0 ?1:rel 
    } 
}

注意:比较规则:

        //自己创建的类要实现是comparable接口,要重写抽象方法; public int compareTo() { }
	//返回0的时候:只有一个元素; //所以我们不能让他返回零
	//返回正数的时候:打印数据 正序输出;
	//返回负数的时候;打印的数据 倒序输出;
	
	//TreeSet 二叉树
	//比我小的数值放到我的左边(返回负数的情况);
	//比我大的数值放到我的右边(返回正数的情况);
	//如果你返回的是零就不存储,
       //集合中保存字符串,按照字符串长度排序;
    	//使用比较器来进行排序;
    	//在比较器中写你的比较规则;
        //利用TreeSet的构造方法 直接将比较器的实现类传进去;
    	     TreeSet<String > set = new TreeSet<>(new StringLengthImpl());//此处传入实现类;
    	     set.add("wanglong");
    	     set.add("kun");
    	     set.add("huxin");
    	     set.add("zhangjianhai");
    	     System.out.println(set);//打印一下就知道有没有实现comparable接口  

例题3:   添加五个人( Person )然后进行排序;

		TreeSet<Person> set = new TreeSet<>();
    	      set.add(new Person("张三",11));
    	      set.add(new Person("张4", 12));
    	      set.add(new Person("张5", 13));
    	      set.add(new Person("张6", 14));
    	      System.out.println((int)'张');
    	      System.out.println((int)'三');
    	      System.out.println(set);

例题4: 排序而且不用去重复(用比较器)  2. 主要按照字符串进行比较,次要按照字符进行比较;

   首先: 使用比较器;

class StringLengthImpl implements Comparator<String> {
	// 实现比较器方法;
	@Override
	public int compare(String o1, String o2) {
		// 实现比较器规则长度比较;
		int length = o1.length() - o2.length();
		// 字符串比较
		int num1 = o1.compareTo(o2);
		int rel = length == 0 ? num1 : length;
		return rel == 0 ? 1 : rel;
	}

}
	private static void 排序2() {
		// 	 要求: 排序,而且还不能去除重复(用比较器)
		   //    主要按字符串长度比较 次要按字符串字符比
		    	          ArrayList<String> set = new ArrayList<>();
		    	          set.add("wanglong");
		    	          set.add("wanglong");
		    	    	      set.add("kun");
		    	    	      set.add("huxin");
		    	    	      set.add("zhangjianhai");
		    	    	      //将接口传进去;
		    	    	      TreeSet<String > set1 = new TreeSet<>(new StringLengthImpl());
		    	    	      set1.addAll(set);
		    	    	      set.clear();
		    	    	      set.addAll(set1);
		    	    	      System.out.println(set1);
	}

例题5: 键盘输入一个字符串,程序对其中所有的字符进行排序.要求保留重复的.

//char比较器
class CharLengthImp implements Comparator<Character>{
	
	@Override
	public int compare(Character o1, Character o2) {
	int num = o1.compareTo(o2);
	//等于零不能删除,等于num判断正负
		return num==0 ?1:num;
	}
}
System.out.println("请输入一个字符串");
    	    Scanner scanner = new Scanner(System.in);
    	    String string= scanner.nextLine();
    	    //字符串转换成字符数组;toCharArray();
    	     char[] array = string.toCharArray();
    	     //创建排序的集合
    	     TreeSet<Character> set = new TreeSet<>(new CharLengthImp());
    	     //将字符数组中的字符添加到Set中;
    	     for (int i = 0; i < array.length; i++) {
    	    	         //将字符数组每一项穿进去;
				set.add(array[i]);
			}
    	     System.out.println(set);

例题6.程序启动后,可以接收多个整数,直到输入quit 时候结束输入,把所有输入的整数倒序排列;

class NumberCompare implements Comparator<Integer>{
	  @Override
	public int compare(Integer o1, Integer o2) {
		int num = o1-o2;
		//如果等于零返回1,否则返回num;
		return num ==0 ? 1 : num;
		//在构造中加入;
	}
}
System.out.println("请输入整数 quit 时候结束;");
		Scanner scanner = new Scanner(System.in);
		TreeSet<Integer> set = new TreeSet<>(new NumberCompare());
		while (true) {
			// 接收用户输入;
			String string = scanner.nextLine();
			// 判断是不是quit
			if (string.equals("quit")) {
				break;
			}
			// 转化成数字;
			int num = Integer.parseInt(string);
			// 保存到集合中排序;
			set.add(num);
		}
		System.out.println(set);

例题7:

/* 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩)
		    录入的学生信息格式(姓名,语文成绩,数学成绩,英语成绩)
		    按照总分从高到低输出到控制台。输出学生所有信息*/
		//创建set保存学生;

创建学生类:

public class Student implements Comparable<Student> {
	private String name;
	private int chinese;
	private int math;
	private int english;
	private int sum;

	public Student(String name, int chinese, int math, int english) {
		super();
		this.name = name;
		this.chinese = chinese;
		this.math = math;
		this.english = english;
		this.sum = chinese + math + english;

	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", chinese=" + chinese + ", math=" + math + ", english=" + english + ", sum="
				+ sum + "]";
	}

	public String getName() {
		return name;
	}

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

	public int getChinese() {
		return chinese;
	}

	public void setChinese(int chinese) {
		this.chinese = chinese;
	}

	public int getMath() {
		return math;
	}

	public void setMath(int math) {
		this.math = math;
	}

	public int getEnglish() {
		return english;
	}

	public void setEnglish(int english) {
		this.english = english;
	}

	public int getSum() {
		return sum;
	}

	public void setSum(int sum) {
		this.sum = sum;
	}

	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}

	//在类中实现
	@Override
	public int compareTo(Student o) {
		int num = this.sum-o.getSum();
		return num==0?1:num;
	}
}
private static void fun7键盘输入数字打印结果() {
		/* 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩)
		    录入的学生信息格式(姓名,语文成绩,数学成绩,英语成绩)
		    按照总分从高到低输出到控制台。输出学生所有信息*/
		//创建set保存学生;
	
		TreeSet<Student> set = new TreeSet<>();
		Scanner scanner = new Scanner(System.in);
		//循环五次;
		while (set.size()<5) {
				System.out.println("请输入学生成绩按照格式姓名,语文成绩,数学成绩,英语成绩");
				//接收用户输入 王龙,150,150,150;
				String string = scanner.nextLine();
				//切割字符串;
				String[] strings = string.split(",");
				//从数组中取出数据
				String name= strings[0];
				int chinese = Integer.parseInt(strings[1]);
				int math = Integer.parseInt(strings[2]);
				int english = Integer.parseInt(strings[3]);
				//创建学生对象;
				 Student student = new Student(name, chinese, math, english);
				 //添加到Set中;
				 set.add(student);
		}
		//遍历集合
		for (Student student : set) {
			System.out.println(student);
		}
	}








      

猜你喜欢

转载自blog.csdn.net/a18755425397/article/details/80409218