JavaSE基础之 自然排序&&泛型与可变参数

it2023-10-07  71

自然排序&&泛型与可变参数

一、自然排序Comparable的使用

1)存储学生对象并遍历,创建TreeSet集合使用无参构造方法 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序

范例:

package Student; import java.util.TreeSet; public class TreeSetDemo { public static void main(String[] args) { //创建集合对象 TreeSet<Student> ts = new TreeSet<Student>(); //创建学生对象 Student s1 = new Student("aaa",14); Student s2 = new Student("bbb",12); Student s3 = new Student("ccc",16); Student s4 = new Student("ddd",15); Student s5 = new Student("eee",15); //把学生添加到集合中 ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); //遍历集合 for (Student s : ts){ System.out.println(s.getName()+","+s.getAge()+"岁"); }//ClassCastException } } public class Student implements Comparable<Student> { String name; 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 compareTo(Student s) { // return 0;//0表示两元素相同,正数表示升序,负数表示降序 int num = this.age - s.age; return num==0? this.name.compareTo(s.name):this.age-s.age; } }

2)用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的。自然排序就是让元素所属的类实现Comparable接口,重写compareTo()方法。重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

3)比较器排序Comparator的使用 存储学生对象并遍历,创建TreeSet集合使用带参构造方法。要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序

范例:

package Student; import java.util.Comparator; import java.util.TreeSet; 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 = s1.getAge() - s2.getAge(); return num == 0 ? s1.getName().compareTo(s2.getName()): s1.getAge() - s2.getAge(); } }); //创建学生对象 Student s1 = new Student("aaa",10); Student s2 = new Student("bbb",11); Student s3 = new Student("ccc",13); Student s4 = new Student("ddd",11); //把学生添加到集合中 ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); //遍历集合 for (Student s :ts){ System.out.println(s.getName()+","+s.getAge()); } } }

4)用TreeSet集合存储自定义对象,用带参构造方法使用的是比较器排序对元素进行排序的。比较器排序就是让集合构造方法接收Comparator的实现类对象,重写compare()方法。重写方法时一定要注意排序规则必须按照要求的主要条件和次要条件来写

5)案例分析:成绩排序 用TreeSet集合存储多个学生信息(姓名,语文成绩,数学成绩),并遍历该集合。要求:总分从低到高出现

//比较器排序: package Student; import java.util.Comparator; import java.util.TreeSet; 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 =s1.getChineseGrade()+s1.getMathGrade()-s2.getChineseGrade()-s2.getMathGrade(); return num==0?s1.getName().compareTo(s2.getName()):num; } }); Student s1 = new Student("aaa",1,2); Student s2 = new Student("bbb",2,2); Student s3 = new Student("ccc",2,1); Student s4 = new Student("ddd",3,2); ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); for (Student s : ts){ System.out.println(s.getName()+" 语文:"+s.getChineseGrade()+" 数学:"+s.getMathGrade()); } } } package Student; public class Student { String name; int age; int ChineseGrade; int mathGrade; public Student(String name, int chineseGrade, int mathGrade) { this.name = name; this.ChineseGrade = chineseGrade; this.mathGrade = mathGrade; } public int getChineseGrade() { return ChineseGrade; } public void setChineseGrade(int chineseGrade) { ChineseGrade = chineseGrade; } public int getMathGrade() { return mathGrade; } public void setMathGrade(int mathGrade) { this.mathGrade = mathGrade; } 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; } } //比较接口实现: package Student; import java.util.Comparator; import java.util.TreeSet; public class TreeSetDemo { public static void main(String[] args) { TreeSet<Student> ts = new TreeSet<Student>(); Student s1 = new Student("aaa",1,2); Student s2 = new Student("bbb",2,2); Student s3 = new Student("ccc",2,1); Student s4 = new Student("ddd",3,2); ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); for (Student s : ts){ System.out.println(s.getName()+" 语文:"+s.getChineseGrade()+" 数学:"+s.getMathGrade()); } } }

6)案例分析:不重复的随机数 要求:编写一个程序,获取10个1-20之间的随机数,要求随机数不能重复,并在控制台输出

范例:

package Student; import java.util.Comparator; import java.util.Random; import java.util.TreeSet; public class TreeSetDemo { public static void main(String[] args) { TreeSet<Integer> ts = new TreeSet<Integer>(); Random r = new Random(); while (ts.size()<11){ Integer i = r.nextInt(20)+1; ts.add(i); } System.out.println("生成的随机数为:"); for (Integer in :ts){ System.out.print(" "+in); } } }

7)泛型:泛型是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型。它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。原理是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型。 这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口

8)泛型定义格式: <类型> : 指定一种类型的格式。这里的类型可以看成形参 <类型1,类型2…> : 指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形参。将来具体调用时候给的类型可以看成是实参,并且实参的类型只能是引用数据类型

9)泛型的好处:把运行时异常转换成编译时异常,避免了强制类型转换

10)泛型类

定义格式: 修饰符 class 类名<类型>{ }

范例: public class Generic<T>{ }

此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型

11)泛型方法 定义格式:修饰符<类型> 返回值类型 方法名(类型 变量名){ }

范例:

public class Generic{ public <T> void show(T t){ System.out.println(t); } }

12)泛型接口:用泛型类实现泛型接口

定义格式:修饰符 interface 接口名<类型>{ }

范例: public interface Generic<T>{ }

13)类型通配符:

为了表示各种泛型List的符类,可以使用类型通配符。类型通配符:<?> List<?>表示元素类型未知的List,它的元素可以匹配任何的类型。这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中。

类型通配符上限:<? extends 类型> List<? extends Number>表示的类型是Number或者其子类型

类型通配符下限:<? super 类型> List<? super Number>表示的类型是Number或者其父类型

14)可变参数:可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了

格式:修饰符 返回值类型 方法名(数据类型… 变量名)

范例:public static int sum(int … a){ }

注意事项:这里的变量a其实是一个数组。如果一个方法有多个参数,包含可变参数,可变参数要放在最后

范例:

public class TreeSetDemo { public static void main(String[] args) { System.out.println(sum(10,20)); System.out.println(sum(10,20,30)); System.out.println(sum(10,20,30,40)); System.out.println(sum(10,20,30,40,50)); System.out.println(sum(10,20,30,40,50,60)); System.out.println(sum(10,20,30,40,50,60,70)); } public static int sum(int...a){ int sum = 0; for(int i :a){ sum+=i; } return sum; } }

15)可变参数的使用 Arrays工具类中有一个静态方法:public static<T> List<T> asList(T…a):返回指定数组支持的固定大小的列表 List接口中有一个静态方法:public static<E> List <E> of(E…elements):返回包含任意数量元素的不可变列表 Set接口中有一个静态方法:public static<E> Set<E> of(E…elements):返回一个包含任意数量元素的不可变集合

最新回复(0)