集合(2)
set集合
不含重复元素集合
没有索引
HashSet:对集合迭代顺序不作保证
public class Demo01 {
public static void main(String[] args) {
Set<String> s = new HashSet<>();
s.add("Hello");
s.add("world");
s.add("cs");
// 遍历
for(String sb : s) {
System.out.println(sb);
}
}
}
hashCode
public class Student { //学生类
private String name;
private 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 int hashCode() {
return 0;
}
}
public class Demo02 {
public static void main(String[] args) {
Student s1 = new Student("陈", 23);
Student s2 = new Student("陈", 23);
//同个对象调用的哈希值相同
//默认下,不同对象的哈希值不同,可通过方法重写使得哈希值相同
System.out.println(s1.hashCode());
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println("world".hashCode());
System.out.println("Hello".hashCode());
System.out.println("重地".hashCode());
System.out.println("通话".hashCode());
}
}
HashSet集合保证元素唯一性
哈希表
存储学生对象,当成员变量相同,认为是同个对象不重复
package com.sheng.hashsetdemo;
import java.util.Objects;
public class Student {
private String name;
private 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 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 &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public class HashSetDemo {
public static void main(String[] args) {
HashSet<Student> hs = new HashSet<Student>();
Student s1 = new Student("王", 23);
Student s2 = new Student("而", 23);
Student s3 = new Student("林", 23);
Student s4 = new Student("林", 23);
hs.add(s1);
hs.add(s2);
hs.add(s4);
hs.add(s3);
for (Student s : hs) {
System.out.println(s.getAge() + "," + s.getName());
}
}
}
LinkHashSet集合
特点:哈希表和链表实现的,具有迭代次序
链表保证有序,哈希表保证元素不重复
使用:
public class LinkHashSetDemo {
public static void main(String[] args) {
LinkedHashSet<String> lhs = new LinkedHashSet<String>();
lhs.add("王");
lhs.add("王二");
lhs.add("王大");
lhs.add("林");
lhs.add("林");
for (String s : lhs) {
System.out.println(s);
}
}
}
TreeSet集合
特点:可以自然排序
没有索引不能使用普通for循环
由于是set集合,不包含重复元素
使用
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Integer> ts = new TreeSet<Integer>();
ts.add(10);
ts.add(11);
ts.add(12);
ts.add(13);
ts.add(14);
ts.add(15);
for (Integer s : ts) {
System.out.println(s);
}
}
}
自然排序Comparable使用
TreeSet无参构造方法存储学生排序,比年龄,比名字字母顺序排序
public class Student implements Comparable<Student> { //必须得实现一下这个接口
private int age;
private String name;
public Student() {
}
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(Student o) {
//return 0;代表相同默认重复,正数代表第二个比第一个大,负数代表比第一个小
int num = this.age - o.age;//this代表第二个,o.age代表第一个
int num2 = num == 0 ? this.name.compareTo(o.name) : num;
return num2;
}
}
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>();
Student s1 = new Student(1, "a");
Student s2 = new Student(2, "b");
Student s3 = new Student(3, "c");
Student s4 = new Student(4, "d");
Student s5 = new Student(4, "e");
Student s6 = new Student(4, "e");
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6);
for (Student s : ts) {
System.out.println(s.getAge() + "," + s.getName());
}
}
}
比较器排序Comparator使用
TreeSet有参构造方法存储学生排序,比年龄,比名字字母顺序排序
public class Student {
private String name;
private 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;
}
}
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
// this.age-s.age
//s1-s2
int num = s1.getAge() - s2.getAge();
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
return num2;
}
});
Student s1 = new Student("a", 12);
Student s2 = new Student("a", 12);
Student s3 = new Student("b", 13);
Student s4 = new Student("c", 13);
Student s5 = new Student("d", 13);
Student s6 = new Student("f", 24);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6);
for (Student s : ts) {
System.out.println(s.getAge() + "," + s.getName());
}
}
}
案例:用 TreeSet集合存储多个学生信息(姓名,语文成绩,数学成绩),并遍历该集合,总分从高到低
法一:比较排序Comparator
public class Student {
private String name;
private int chinese;
private int math;
public Student() {
}
public Student(String name, int chinese, int math) {
this.name = name;
this.chinese = chinese;
this.math = math;
}
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 sum() {
return this.chinese + this.math;
}
}
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num = s2.sum() - s1.sum();
int num2 = num == 0 ? s2.getChinese() - s1.getChinese() : num;
int num3 = num2 == 0 ? s2.getName().compareTo(s1.getName()) : num2;
return num3;
}
});
Student s1 = new Student("林", 100, 99);
Student s2 = new Student("林", 100, 99);
Student s3 = new Student("赵云", 98, 97);
Student s4 = new Student("小", 88, 96);
Student s5 = new Student("大", 87, 99);
Student s6 = new Student("马超", 33, 28);
Student s7 = new Student("陈", 100, 99);
Student s8 = new Student("木", 100, 99);
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.getChinese() + "," + s.getMath() + "," + s.sum());
}
}
}
法二:自然排序Comparable
public class Student implements Comparable<Student> {
private String name;
private int chinese;
private int math;
public Student() {
}
public Student(String name, int chinese, int math) {
this.name = name;
this.chinese = chinese;
this.math = math;
}
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 getSum() {
return this.chinese + this.math;
}
@Override
public int compareTo(Student s) {
int num = s.getSum() - this.getSum();
int num2 = num == 0 ? s.chinese - this.chinese : num;
int num3 = num2 == 0 ? s.name.compareTo(this.name) : num2;
return num3;
}
}
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<Student>();
Student s1 = new Student("lin", 100, 99);
Student s2 = new Student("lin", 100, 99);
Student s3 = new Student("赵云", 98, 97);
Student s4 = new Student("小", 88, 96);
Student s5 = new Student("大", 87, 99);
Student s6 = new Student("马超", 33, 28);
Student s7 = new Student("陈", 100, 99);
Student s8 = new Student("木", 100, 99);
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.getChinese() + "," + s.getMath() + "," + s.getSum());
}
}
}
案例:获取10个1-20随机数,随机数不重复
public class hashsetdemo {
public static void main(String[] args) {
Set<Integer> s = new HashSet<Integer>();
Random r = new Random();
while (s.size() < 10) {
int num = r.nextInt(20) + 1;
s.add(num);
}
for (Integer i : s) {
System.out.println(i);
}
}
}
泛型
好处:运行问题提前到编译期间
避免强制类型转换
泛型类
public class Generic<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
public class GenericTest {
public static void main(String[] args) {
Generic<String> g = new Generic<String>();
g.setT("林");
System.out.println(g.getT());
Generic<Integer> g1 = new Generic<Integer>();
g1.setT(30);
System.out.println(g1.getT());
Generic<Boolean> g2 = new Generic<Boolean>();
g2.setT(true);
System.out.println(g2.getT());
}
}
泛型方法
public class Generic {
public <T> void show(T t) {
System.out.println(t);
}
}
public class Demo {
public static void main(String[] args) {
Generic g = new Generic();
g.show(10);
g.show("s");
g.show(true);
System.out.println(g);
}
}
泛型接口
public interface Generic<T> {
void show(T t);
}
public class GenericImpl<T> implements Generic<T> {
@Override
public void show(T t) {
System.out.println(t);
}
}
public class GenericDemo {
public static void main(String[] args) {
Generic<String> g = new GenericImpl<String>();
g.show("LIN");
Generic<Integer> g1= new GenericImpl<Integer>();
g1.show(100);
}
}
类型通配符
类型通配符: <?> 任何类型
类型通配符上限: <? extends 类型>
List<? extends Number> :它表示的类型是Number或者其子类型
类型通配符下限: <? super 类型>
List<? super Number> :它表示的类型是Number或者其父类型
public class Demo {
public static void main(String[] args) {
List<?> s = new ArrayList<Number>();
List<?> s1 = new ArrayList<Object>();
List<?> s2 = new ArrayList<Integer>();
//上限
List<? extends Number> s3 = new ArrayList<Integer>();
//下限
List<? super Number> s4 = new ArrayList<Object>();
}
}
可变参数
修饰符 返回值类型 方法名(数据类型… 变量名) { }
public class Demo01 {
public static void main(String[] args) {
System.out.println(sum(1, 2, 3, 4, 5));
}
public static int sum(int... a) {
int sum = 0;
for (int i : a) {
sum = sum + i;
}
return sum;
}
}
可变参数使用
Arrays 工具类中有一个静态方法:
List asList(T… a):返回由指定数组支持的固定大小的列表
不能做增删操作,可以做修改操作
List 接口中有一个静态方法:
List of(E… elements):返回包含任意数量元素的不可变列表
Set 接口中有一个静态方法:
Set of(E… elements) :返回一个包含任意数量元素的不可变集合
不重复元素
public class Demo02 {
public static void main(String[] args) {
// List asList(T... a):返回由指定数组支持的固定大小的列表
List<String> s = Arrays.asList("s", "c", "cs");
s.set(1,"cs");
System.out.println(s);
// List of(E... elements):返回包含任意数量元素的不可变列表
// List<String> list = List.of("s", "c", "cs");jdk9以后才有
// Set of(E... elements) :返回一个包含任意数量元素的不可变集合
// Set<String> set = Set.of("hello", "world", "java");jdk9以后才有
}
}