31.4 ArrayList
List集合子类特点
List集合常用子类:ArrayList, LinkedList
- ArrayList:底层数据结构是数组,查询快,增删慢
- LinkedList:底层数据结构是链表,查询慢,增删快
练习:
package myList.Demo7; import java.util.ArrayList; import java.util.LinkedList; import java.util.ListIterator; /* List集合常用子类:ArrayList LinkedList ArrayList: 底层数据结构是数组,查询快,增删慢 LinkedList: 底层数据结构是链表,查询慢,增删快 练习:分别使用完成存储字符串并遍历 */ public class Demo1 { public static void main(String[] args) { //创建集合对象 ArrayList<String> array = new ArrayList<>(); array.add("hello"); array.add("world"); array.add("java"); for (String s : array) { System.out.println(s); } System.out.println("------------------------"); LinkedList<String> linkedList = new LinkedList<>(); linkedList.add("hello"); linkedList.add("world"); linkedList.add("javaee"); ListIterator<String> lit = linkedList.listIterator(); while(lit.hasNext()){ String s = lit.next(); System.out.println(s); } } }
案例:ArrayList集合存储学生对象用三种方法遍历
Student类不重复
package myList.Demo8; import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator; public class Demo1 { public static void main(String[] args) { //创建集合对象 ArrayList<Student> array = new ArrayList<>(); //创建学生对象 Student s1 = new Student("林青霞", 18); Student s2 = new Student("张曼玉", 19); Student s3 = new Student("王祖贤", 20); //集合添加元素 array.add(s1); array.add(s2); array.add(1, s3); //遍历 //1.for for (int i = 0; i < array.size(); i++) { Student s = array.get(i); System.out.println(s); } System.out.println("--------------------------"); //2.增强for for (Student s : array) { System.out.println(s); } System.out.println("--------------------------"); //3. ListIterator<Student> lit = array.listIterator(); while (lit.hasNext()) { Student s = lit.next(); System.out.println(s); } System.out.println("--------------------------"); //4. Iterator<Student> it = array.iterator(); while (it.hasNext()) { Student s = it.next(); System.out.println(s); } } }
31.5 LinkedList
LinkedList集合的特有功能
package myList.Demo9; import java.util.LinkedList; /* LinkedList集合的特有功能: public void addFirst(E e): 在该列表开头插入指定的元素 public void addLast(E e): 将指定的元素追加到此列表的末尾 public E getFirst(): 返回此列表中的第一个元素 public E getLast(): 返回此列表中的最后一个元素 public E removeFirst(): 从此列表中删除并返回第一个元素 public E removeLast(): 从此列表中删除并返回最后一个元素 */ public class Demo1 { public static void main(String[] args) { LinkedList<String> linkedList = new LinkedList<>(); //添加 linkedList.add("world"); linkedList.addFirst("hello"); linkedList.addLast("java"); System.out.println(linkedList); System.out.println("----------------------"); //get System.out.println("get第一个:" + linkedList.getFirst()); System.out.println("get最后一个:" + linkedList.getLast()); System.out.println("-----------------------"); //remove System.out.println("移除第一个:" + linkedList.removeFirst()); System.out.println("移最后一个:" + linkedList.removeLast()); System.out.println("linkedList:" + linkedList); } }
31.6 Set集合
无序,不含重复元素
Set集合特点
- 不包含重复元素
- 没有带索引的方法,所以不能使用欧通for循环遍历
package mySet.Demo1; import java.util.HashSet; import java.util.Set; /* Set集合特点 不包含重复元素的集合 没有带索引的方法,所以不能使用普通for循环遍历 HashSet: 对集合的迭代顺序不作任何保证 */ public class Demo1 { public static void main(String[] args) { //创建集合对象 Set<String> set = new HashSet<>(); //添加元素 set.add("hello"); set.add("world"); set.add("java"); //不包含重复元素 set.add("world"); //遍历 for (String s : set) { System.out.println(s); } } }
31.7 哈希值
哈希值:是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
Object类中有一个方法可以获取对象的哈希值
public int hashCode()
:返回对象的哈希码值
对象的哈希值特点
- 同一个对象多次调用hashCode()方法返回的哈希值是相同的
- 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象哈希值相同
代码如下:
Student.java这里就不再写了
package mySet.Demo2; /* 哈希值: 是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值 Object类中有一个方法可以获取对象的哈希值 public int hashCode(): 返回对象的哈希码值 */ public class Demo1 { public static void main(String[] args) { //创建学生对象 Student s1 = new Student("林青霞", 18); //同一个对象多次调用hashCode()方法返回的哈希值是相同的 System.out.println(s1.hashCode()); System.out.println(s1.hashCode()); //1239731077 //默认情况下 不同对象的哈希值是不相同的 Student s2 = new Student("林青霞", 18); System.out.println(s2.hashCode()); System.out.println(s2.hashCode()); //557041912 //通过方法重写,可以实现不同独享的哈希值是相同的 System.out.println("---------------------------"); System.out.println("hello".hashCode()); System.out.println("world".hashCode()); System.out.println("java".hashCode()); System.out.println("-------------------"); System.out.println("重地".hashCode()); //这两个一样! 字符串重写了哈希值的方法 System.out.println("通话".hashCode()); } }
31.8 HashSet集合
无序,不含重复元素
package mySet.Demo3; import java.util.HashSet; /* HashSet集合的特点 1.底层数据结构是哈希表 2.对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致 3.没有带索引的方法,所以不能使用普通for循环遍历 4.由于是Set集合,所以是不包含重复元素的集合 */ public class Demo1 { public static void main(String[] args) { //创建集合对象 HashSet<String> hs = new HashSet<>(); hs.add("hello"); hs.add("world"); hs.add("java"); //不包含重复元素 hs.add("hello"); System.out.println(hs); //遍历 for (String s : hs) { System.out.println(s); } } }
案例:HashSet集合存储学生对象并遍历
Student.java
package mySet.Demo4; 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; if (age != student.age) return false; return name != null ? name.equals(student.name) : student.name == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + age; return result; } }
Demo1.java
package mySet.Demo4; import java.util.HashSet; public class Demo1 { public static void main(String[] args) { //创建HashSet集合对象 HashSet<Student> ha = new HashSet<>(); //创建学生对象 Student s1 = new Student("林青霞", 18); Student s2 = new Student("张曼玉", 19); Student s3 = new Student("王祖贤", 20); Student s4 = new Student("王祖贤", 20); //因为是new,这里会默认s3和s4不一样, 所以需要重写HashCode和equals ha.add(s1); ha.add(s2); ha.add(s3); ha.add(s4); for (Student s : ha) { System.out.println(s.getName() + "," + s.getAge()); } } }
31.9 LinkedHashSet集合
这个是有序的,不含重复元素
package mySet.Demo5; import java.util.LinkedHashSet; /* LinkedHashSet集合特点 1.哈希表和链表实现的Set接口,具有可预测的迭代次序 2.由链表保证元素有序,也就是说元素的存储和去除顺序一致 3.由哈希表保证元素唯一,就是没有重复元素 */ public class Demo1 { public static void main(String[] args) { //创建集合对象 LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>(); //添加元素 linkedHashSet.add("hello"); linkedHashSet.add("world"); linkedHashSet.add("java"); linkedHashSet.add("world"); System.out.println(linkedHashSet); //遍历 for(String s:linkedHashSet){ System.out.println(s); } } }
31.10 TreeSet集合
有序,不含重复元素
Student.java
package mySet.Demo6; public class Student implements Comparable<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 String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compareTo(Student s) { // return 0; // return 1; int num = this.age - s.age; int num2 = num == 0 ? this.name.compareTo(s.name) : num; return num2; } }
Demo1.java
package mySet.Demo6; import java.util.TreeSet; /* TreeSet集合特点 1.元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法 TreeSet(): 根据其元素的自然排序进行排序 TreeSet(Comparator comparator): 根据指定的比较器进行排序 2.没有带索引的方法,所以不能使用普通for循环遍历 3.由于是Set集合,所以不包含重复元素 */ public class Demo1 { public static void main(String[] args) { //创建集合对象 TreeSet<Integer> ts = new TreeSet<>(); //添加元素 ts.add(10); ts.add(40); ts.add(30); ts.add(50); ts.add(20); //重复元素 ts.add(30); System.out.println(ts); //自然排序 //遍历 for (Integer i : ts) { System.out.println(i); } } }
31.11 自然排序Comparable的使用
案例:
Student.java
Demo2.java
package mySet.Demo6; import java.util.TreeSet; /* 存储学生对象并遍历,创建集合使用无参构造方法 要求:按照年龄的从小到大排序,年龄相同时,按照姓名的字母顺序排序 */ public class Demo2 { public static void main(String[] args) { //创建集合对象 TreeSet<Student> ts = new TreeSet<Student>(); //创建学生对象 Student s1 = new Student("xishi", 29); Student s2 = new Student("wangzhaojun", 28); Student s3 = new Student("diaochan", 30); Student s4 = new Student("yangyuhuan", 33); Student s5 = new Student("linqingxia", 33); Student s6 = new Student("linqingxia", 33); //添加 ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); System.out.println(ts); //遍历 for (Student s : ts) { System.out.println(s.getName() + "," + s.getAge()); } } }
31.12 比较器排序Comparator的使用
package mySet.Demo7; import java.util.Comparator; import java.util.TreeSet; /* 存储学生对象并遍历,创建集合使用带参构造方法 要求:按照年龄的从小到大排序,年龄相同时,按照姓名的字母顺序排序 */ public class Demo1 { 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(); int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; return num2; } }); //创建学生对象 Student s1 = new Student("xishi", 29); Student s2 = new Student("wangzhaojun", 28); Student s3 = new Student("diaochan", 30); Student s4 = new Student("yangyuhuan", 33); Student s5 = new Student("linqingxia", 33); Student s6 = new Student("linqingxia", 33); //添加 ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); System.out.println(ts); //遍历 for (Student s : ts) { System.out.println(s.getName() + "," + s.getAge()); } } }
与上一小节输出同样的结果
案例:成绩排序
Demo1.java
package mySet.Demo8; import java.util.Comparator; import java.util.TreeSet; /* 需求: 用TreeSet集合存储多个学生信息(姓名, 语文成绩, 数学成绩), 并遍历该集合 要求:按照总分从高到低出现 思路: 1.定义学生类 2.创建TreeSet集合对象,通过比较器排序进行排序 3.创建学生对象 4.把学生对象添加到集合 5.遍历集合 */ public class Demo1 { public static void main(String[] args) { //创建集合对象 TreeSet<Student> ts = new TreeSet<>(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.getName().compareTo(s2.getName()) : num2; return num3; } }); //创建学生对象 Student s1 = new Student("林青霞", 98, 100); Student s2 = new Student("张曼玉", 95, 95); Student s3 = new Student("王祖贤", 100, 93); Student s4 = new Student("成德善", 100, 97); Student s5 = new Student("风清扬", 98, 98); Student s6 = new Student("左冷禅", 97, 99); Student s7 = new Student("张三", 97, 99); //添加 ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); ts.add(s7); System.out.println(ts); //遍历 for (Student s : ts) { System.out.println(s.getName() + "," + s.getChinese() + "," + s.getMath() + "," + s.getSum()); } } }
案例:不重复的随机数
package mySet.Demo9; import java.util.HashSet; import java.util.Random; import java.util.Set; import java.util.TreeSet; public class Demo9 { public static void main(String[] args) { //创建集合 Set<Integer> set = new HashSet<>(); //Set<Integer> set = new TreeSet<>(); //创建随机数对象 Random r = new Random(); //判断是否10个 while (set.size() < 10) { //产生一个随机数,添加到集合 int number = r.nextInt(20) + 1; //1-20之间 set.add(number); } System.out.println(set); //遍历集合 for (Integer i : set) { System.out.println(i); } } }
32 泛型
32.1 泛型概述
package myGeneric.Demo1; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; //需求:Collection集合存储字符串并遍历 public class Demo1 { public static void main(String[] args) { //创建集合对象 //Collection c =new ArrayList(); Collection<String> c =new ArrayList(); //String泛型 //添加元素 c.add("hello"); c.add("world"); c.add("java"); // c.add(100); //ClassCastException //遍历 // Iterator it = c.iterator(); Iterator<String> it = c.iterator(); while(it.hasNext()){ // Object obj = it.next(); // System.out.println(obj); // String s = (String)it.next(); String s = it.next(); System.out.println(s); } } }
32.2 泛型类
Generic.java
package myGeneric.Demo2; public class Generic<T> { private T t; public T getT() { return t; } public void setT(T t) { this.t = t; } }
Demo1.java
package myGeneric.Demo2; public class Demo1 { public static void main(String[] args) { Generic<String> g1 = new Generic<>(); g1.setT("林青霞"); System.out.println(g1.getT()); Generic<Integer> g2 = new Generic<>(); g2.setT(30); System.out.println(g2.getT()); Generic<Boolean> g3 = new Generic<>(); g3.setT(true); System.out.println(g3.getT()); } }
32.3 泛型方法
版本一:
Generic.java
package myGeneric.Demo3; public class Generic { public void show(String s){ System.out.println(s); } public void show(Integer i){ System.out.println(i); } public void show(Boolean b){ System.out.println(b); } }
Demo1.java
package myGeneric.Demo3; public class Demo1 { public static void main(String[] args) { Generic g = new Generic(); g.show("林青霞"); g.show(30); g.show(true); //g.show(12.34); //报错 } }
版本二:
Generic.java
package myGeneric.Demo3; //泛型类改进 public class Generic<T>{ public void show(T t){ System.out.println(t); } }
Demo1.java
package myGeneric.Demo3; public class Demo1 { public static void main(String[] args) { Generic<String> g1 = new Generic<>(); g1.show("林青霞"); Generic<Integer> g2 = new Generic<>(); g2.show(30); Generic<Boolean> g3 = new Generic<>(); g3.show(true); Generic<Double> g4 = new Generic<>(); g4.show(12.34); } }
版本三:
Generic.java
package myGeneric.Demo3; //泛型方法改进 public class Generic { public <T> void show(T t){ System.out.println(t); } }
Demo1.java
package myGeneric.Demo3; public class Demo1 { public static void main(String[] args) { Generic g = new Generic(); g.show("林青霞"); g.show(30); g.show(true); g.show(12.34); } }
32.4 泛型接口
Generic.java
package myGeneric.Demo4; public interface Generic<T> { void show(T t); }
GenericImpl.java
package myGeneric.Demo4; public class GenericImpl<T> implements Generic<T> { @Override public void show(T t) { System.out.println(t); } }
Demo1.java
package myGeneric.Demo4; public class Demo1 { public static void main(String[] args) { Generic<String> g1 = new GenericImpl<>(); g1.show("林青霞"); Generic<Integer> g2 = new GenericImpl<>(); g2.show(30); } }