集合和泛型
集合的分类
Collection
Map
Set接口:无序不重复
HashSet:无序不重复
TreeSet:有序不重复
如何去重?
首先使用hashcode判定,如果值不等则肯定对象不等,如果值相等则要再使用equals进行比对。
迭代器
Iterator it = hashSet.iterator();
while(it.hasNext()){
int i = (int)it.next();
}
一般不使用迭代器进行集合遍历,而使用增强for循环。
for(Object:obj Set){
System.out.println(obj);
}
比较器
当两个对象进行比较的时候,需要定义比较规则。这时候就需要使用比较器。
比较器由两种:内部比较器和外部比较器。
内部比较器
用要比较的类实现Comparatable接口,重写compareTo()方法
@Override
public int compareTo(Student stu) {
return this.getGrade()- stu.getGrade();//按成绩递增排序 成绩相同的会去重
}
外部比较器
重新定义一个类用来实现Comparator接口,重写compare()方法
import java.util.Comparator;
public class StudentCom implements Comparator<Student> {
@Override
public int compare(Student stu1, Student stu2) {
return stu1.getGrade()- stu2.getGrade();//按成绩递增排序
}
}
List接口:有序可重复
ArrayList:优点循环遍历,缺点增删。
LinkedList:优点增删,缺点循环遍历。
增加了对队列和栈模型的操作优化,例如;addFirst(),addLast(),getFirst()等。
import java.util.LinkedList;
public class Test {
public static void main(String[] args) {
LinkedList<Student> list = new LinkedList<>();
list.add(new Student(3,"king"));
list.add(new Student(1,"david"));
list.add(new Student(2,"tom"));
list.add(new Student(3,"king"));
for (Student student : list) {
System.out.println(student);//要重写toString()方法
}
System.out.println();
list.sort(new StudentComp());//用StudentComp类实现Comparator<>并重写compare()方法
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
Map接口
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
Map<Integer,String>map = new HashMap<>();//泛型里必须是Integer,Integer是int的包装类;int是基本数据类型,integer是引用类型
map.put(1, "lili");
map.put(2,"lucy");
map.put(2,"marry");
map.put(6,"tuhu");
map.put(3,"lulu");
Set<Integer> set =map.keySet();
for(Integer key: set){
System.out.println(key+"|"+map.get(key));
}
for(String value: map.values()){
System.out.println(value);
}
}
}
泛型里必须是Integer,Integer是int的包装类;int是基本数据类型,integer是引用类型
工具类
- 集合
- 数组
自动装箱与拆箱
基本类型如何存入集合?
8个基本类型都有与之对应的封装类。在基本类型存入集合的时候是这样的:
int -> Integer -> Object
在jdk1.5以后由int -> Integer的操作由JVM自动进行,就是自动装箱。反之Integer -> int拆箱。
泛型
why:集合对象中存储的都是Object类型的对象,存储时子类可以自动转换为Object。当需要读取数据时则需要强制将Object类型转换成子类,这是不安全的行为。使用泛型可以约束存入数据类型。提高数据安全性。
what:
泛型:是一种约束,可以在代码编译阶段对存储于集合的数据进行类型控制。
泛型擦除:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。
where:使用集合时必须使用泛型做数据类型约束,使用泛型后的集合可以使用增强for循环迭代。
how:
- 集合泛型
List<String> strList = new ArrayList<>();
- 泛型类
/*
1:把泛型定义在类上
2:类型变量定义在类上,方法中也可以使用
*/
public class ObjectTool<T> {
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
- 泛型方法
public <T> void show(T t) {
System.out.println(t);
}
例子:
成绩从高到低排序,成绩相同的按名字排序
- Student类
public class Student{
private int grade;
private String name;
public Student(int grade,String name) {
this.grade = grade;
this.name = name;
}
public int getGrade() {
return grade;
}
public String getName() {
return name;
}
public void setGrade(int grade) {
this.grade = grade;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"grade=" + grade +
", name='" + name + '\'' +
'}';
}
}
- StudentCom类
import java.util.Comparator;
public class StudentCom implements Comparator<Student> {
@Override
public int compare(Student stu1, Student stu2) {
if(stu1.getGrade()!= stu2.getGrade())
return stu1.getGrade()- stu2.getGrade();
else return stu1.getName().compareTo(stu2.getName());
}
}
- Test
import java.util.Set;
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
Set<Student> set = new TreeSet(new StudentCom());
set.add(new Student(98,"lili"));
set.add(new Student(98,"jimmy"));
set.add(new Student(90,"lucy"));
for (Object obj:set) {
System.out.println(obj);
}
}
}
- 运行结果