java_Set_son

Set_Son

(1)

1.

package cn.itcast_01;

import java.util.HashSet;

import java.util.Set;

/*

 * Collection

 * |--List

 * 有序(存储顺序和取出顺序一致),可重复

 * |--Set

 * 无序(存储顺序和取出顺序不一致),唯一

 *

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

 * 注意:虽然Set集合的元素无序,但是,作为集合来说,它肯定有它自己的存储顺序,

 * 而你的顺序恰好和它的存储顺序一致,这代表不了有序,你可以多存储一些数据,就能看到效果。

 */

public class SetDemo {

public static void main(String[] args) {

// 创建集合对象

Set<String> set = new HashSet<String>();

// 创建并添加元素

set.add("hello");

set.add("java");

set.add("world");

set.add("java");

set.add("world");

// 增强for

for (String s : set) {

System.out.println(s);

}

}

}

2.

/*

 * HashSet:存储字符串并遍历

 * 问题:为什么存储字符串的时候,字符串内容相同的只存储了一个呢?

 * 通过查看add方法的源码,我们知道这个方法底层依赖 两个方法:hashCode()和equals()。

 * 步骤:

 * 首先比较哈希值

 * 如果相同,继续走,比较地址值或者走equals()

 * 如果不同,就直接添加到集合中

 * 按照方法的步骤来说:

 * 先看hashCode()值是否相同

 * 相同:继续走equals()方法

 * 返回true: 说明元素重复,就不添加

 * 返回false:说明元素不重复,就添加到集合

 * 不同:就直接把元素添加到集合

 * 如果类没有重写这两个方法,默认使用的Object()。一般来说不同相同。

 * 而String类重写了hashCode()和equals()方法,所以,它就可以把内容相同的字符串去掉。只留下一个。

 */

public class HashSetDemo2 {

public static void main(String[] args) {

// 创建集合对象

HashSet<Student> hs = new HashSet<Student>();

// 创建学生对象

Student s1 = new Student("林青霞", 27);

Student s2 = new Student("柳岩", 22);

Student s3 = new Student("王祖贤", 30);

Student s4 = new Student("林青霞", 27);

Student s5 = new Student("林青霞", 20);

Student s6 = new Student("范冰冰", 22);

// 添加元素

hs.add(s1);

hs.add(s2);

hs.add(s3);

hs.add(s4);

hs.add(s5);

hs.add(s6);

// 遍历集合

for (Student s : hs) {

System.out.println(s.getName() + "---" + s.getAge());

}

}

}

在学生类里面编辑如下:

package HashSetStudent;

public class Student {

//定义私有成员

private String name;

private int age;

//定义无参数构造

public Student() {}

//带参数构造方法

public Student(String name,int age) {

super();

this.name=name;

this.age=age;

}

//set/get方法

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

}

//生成hashcodeequal()

}

3. 如果采用了LinkedHashSet就没有必要在用HashSet(因为HashSet依赖于hashcode()和equal(),由String重写这两个方法。)

/*

 * LinkedHashSet:底层数据结构由哈希表和链表组成。

 * 哈希表保证元素的唯一性。

 * 链表保证元素有素。(存储和取出是一致)

 */

public class LinkedHashSetDemo {

public static void main(String[] args) {

// 创建集合对象

LinkedHashSet<String> hs = new LinkedHashSet<String>();

// 创建并添加元素

hs.add("hello");

hs.add("world");

hs.add("java");

hs.add("world");

hs.add("java");

// 遍历

for (String s : hs) {

System.out.println(s);

}

}

}

                 TreeSet

1.在用学生类的时候,需要修改学生类:

1)在学生类的前面添加implements Comparable<Student> ,把学生类当作一个接口。(2)重写public int compareTo(Student s)方法。

public int compareTo(Student s)  {

// return 0;(怎么进去怎么出来)

// return 1;(把年龄相同的去掉了)

// return -1;(反过来,倒着排序)

// 这里返回什么,其实应该根据我的排序规则来做

// 按照年龄排序,主要条件

int num = this.age - s.age;

// 次要条件

// 年龄相同的时候,还得去看姓名是否也相同

// 如果年龄和姓名都相同,才是同一个元素

int num2 = num == 0 ? this.name.compareTo(s.name) : num;

return num2;

2.注意另一个例子学生类的重写

public int compareTo(Student s) {

// 主要条件 姓名的长度

int num = this.name.length() - s.name.length();

// 姓名的长度相同,不代表姓名的内容相同

int num2 = num == 0 ? this.name.compareTo(s.name) : num;

// 姓名的长度和内容相同,不代表年龄相同,所以还得继续判断年龄

int num3 = num2 == 0 ? this.age - s.age : num2;

return num3;

}

}

3.比较器排序

package cn.itcast_07;

import java.util.Comparator;

import java.util.TreeSet;

/*

 * 需求:请按照姓名的长度排序

 *

 * TreeSet集合保证元素排序和唯一性的原理

 * 唯一性:是根据比较的返回是否是0来决定。

 * 排序:

 * A:自然排序(元素具备比较性)

 * 让元素所属的类实现自然排序接口 Comparable

 * B:比较器排序(集合具备比较性)

 * 让集合的构造方法接收一个比较器接口的子类对象 Comparator

 */

public class TreeSetDemo {

public static void main(String[] args) {

// 创建集合对象

// TreeSet<Student> ts = new TreeSet<Student>(); //自然排序

// public TreeSet(Comparator comparator) //比较器排序

// TreeSet<Student> ts = new TreeSet<Student>(new MyComparator());

// 如果一个方法的参数是接口,那么真正要的是接口的实现类的对象

// 而匿名内部类就可以实现这个东西

TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {

@Override

public int compare(Student s1, Student s2) {

// 姓名长度

int num = s1.getName().length() - s2.getName().length();

// 姓名内容

int num2 = num == 0 ? s1.getName().compareTo(s2.getName())

: num;

// 年龄

int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;

return num3;

}

});

// 创建元素

Student s1 = new Student("linqingxia", 27);

Student s2 = new Student("zhangguorong", 29);

Student s3 = new Student("wanglihong", 23);

Student s4 = new Student("linqingxia", 27);

Student s5 = new Student("liushishi", 22);

Student s6 = new Student("wuqilong", 40);

Student s7 = new Student("fengqingy", 22);

Student s8 = new Student("linqingxia", 29);

// 添加元素

ts.add(s1);

ts.add(s2);

ts.add(s3);

ts.add(s4);

ts.add(s5);

ts.add(s6);

ts.add(s7);

ts.add(s8);

// 遍历

for (Student s : ts) {

System.out.println(s.getName() + "---" + s.getAge());

}

}

}

 

注意:比较器排序的student类没有做修改

 

 

4.例子

package cn.itcast_08;

import java.util.HashSet;

import java.util.Random;

 

/*

 * 编写一个程序,获取10个1至20的随机数,要求随机数不能重复。

 *

 * 分析:

 * A:创建随机数对象

 * B:创建一个HashSet集合

 * C:判断集合的长度是不是小于10

 * 是:就创建一个随机数添加

 * 否:不搭理它

 * D:遍历HashSet集合

 */

public class HashSetDemo {

public static void main(String[] args) {

// 创建随机数对象

Random r = new Random();

 

// 创建一个Set集合

HashSet<Integer> ts = new HashSet<Integer>();

 

// 判断集合的长度是不是小于10

while (ts.size() < 10) {

int num = r.nextInt(20) + 1;

ts.add(num);

}

 

// 遍历Set集合

for (Integer i : ts) {

System.out.println(i);

}

}

}

 

 

 

 

5.例子

1)student

package cn.itcast_08;

 

public class Student {

// 姓名

private String name;

// 语文成绩

private int chinese;

// 数学成绩

private int math;

// 英语成绩

private int english;

 

public Student(String name, int chinese, int math, int english) {

super();

this.name = name;

this.chinese = chinese;

this.math = math;

this.english = english;

}

 

public Student() {

super();

}

 

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 this.chinese + this.math + this.english;

}

}

 

2)实现类

package cn.itcast_08;

import java.util.Comparator;

import java.util.Scanner;

import java.util.TreeSet;

 

/*

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

 *

 * 分析:

 * A:定义学生类

 * B:创建一个TreeSet集合

 * C:总分从高到底如何实现呢?

 * D:键盘录入5个学生信息

 * E:遍历TreeSet集合

 */

public class TreeSetDemo {

public static void main(String[] args) {

// 创建一个TreeSet集合

TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {

@Override

public int compare(Student s1, Student s2) {

// 总分从高到低

int num = s2.getSum() - s1.getSum();

// 总分相同的不一定语文相同

int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num;

// 总分相同的不一定数序相同

int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2;

// 总分相同的不一定英语相同

int num4 = num3 == 0 ? s1.getEnglish() - s2.getEnglish() : num3;

// 姓名还不一定相同呢

int num5 = num4 == 0 ? s1.getName().compareTo(s2.getName())

: num4;

return num5;

}

});

 

System.out.println("学生信息录入开始");

// 键盘录入5个学生信息

for (int x = 1; x <= 5; x++) {

Scanner sc = new Scanner(System.in);

System.out.println("请输入第" + x + "个学生的姓名:");

String name = sc.nextLine();

System.out.println("请输入第" + x + "个学生的语文成绩:");

String chineseString = sc.nextLine();

System.out.println("请输入第" + x + "个学生的数学成绩:");

String mathString = sc.nextLine();

System.out.println("请输入第" + x + "个学生的英语成绩:");

String englishString = sc.nextLine();

 

// 把数据封装到学生对象中

Student s = new Student();

s.setName(name);

s.setChinese(Integer.parseInt(chineseString));

s.setMath(Integer.parseInt(mathString));

s.setEnglish(Integer.parseInt(englishString));

 

// 把学生对象添加到集合

ts.add(s);

}

System.out.println("学生信息录入完毕");

 

System.out.println("学习信息从高到低排序如下:");

System.out.println("姓名\t语文成绩\t数学成绩\t英语成绩");

// 遍历集合

for (Student s : ts) {

System.out.println(s.getName() + "\t" + s.getChinese() + "\t"

+ s.getMath() + "\t" + s.getEnglish());

}

}

}

 

猜你喜欢

转载自blog.csdn.net/qq_37606901/article/details/80801901
SON