1.集合概述及继承体系图
A:集合的由来
数组长度是固定,当添加的元素超过了数组的长度时需要对数组重新定义,太麻烦,java内部给我们提供了集合类,能存储任意对象,长度是可以改变的,随着元素的增加而增加,随着元素的减少而减少
B:数组和集合的区别
区别1 :
数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值
集合只能存储引用数据类型(对象)集合中也可以存储基本数据类型,但是在存储的时候会自动装箱变成对象
区别2:
数组长度是固定的,不能自动增长
集合的长度的是可变的,可以根据元素的增加而增长
C:数组和集合什么时候用 * 1,如果元素个数是固定的推荐用数组 * 2,如果元素个数不是固定的推荐用集合
D:集合继承体系图
2.Collection集合的基本功能测试
A:案例演示
基本功能演示
boolean add(E e)
boolean remove(Object o)
void clear()
boolean contains(Object o)
boolean isEmpty()
int size()
3.集合的遍历之集合转数组遍历
A:集合的遍历
其实就是依次获取集合中的每一个元素。
B:案例演示
把集合转成数组,可以实现集合的遍历
toArray()
```java Collection coll = new ArrayList(); coll.add(new Student("张三",23)); //Object obj = new Student("张三",23); coll.add(new Student("李四",24)); coll.add(new Student("王五",25)); coll.add(new Student("赵六",26));
Object[] arr = coll.toArray(); //将集合转换成数组 for (int i = 0; i < arr.length; i++) { Student s = (Student)arr[i]; //强转成Student System.out.println(s.getName() + "," + s.getAge()); } ```
4.Collection集合的带All功能测试
A:案例演示
带All的功能演示
java boolean addAll(Collection c) boolean removeAll(Collection c) boolean containsAll(Collection c) boolean retainAll(Collection c)
5.集合的遍历之迭代器遍历
A:迭代器概述
集合是用来存储元素,存储的元素需要查看,那么就需要迭代(遍历)
B:案例演示
迭代器的使用
```java
Collection c = new ArrayList(); c.add("a"); c.add("b"); c.add("c"); c.add("d"); Iterator it = c.iterator(); //获取迭代器的引用 while(it.hasNext()) { //集合中的迭代方法(遍历) System.out.println(it.next()); } ```
6.Collection存储自定义对象并遍历
A:案例演示
Collection存储自定义对象并用迭代器遍历
Collection c = new ArrayList();
```java c.add(new Student("张三",23)); c.add(new Student("李四",24)); c.add(new Student("王五",25)); c.add(new Student("赵六",26)); c.add(new Student("赵六",26));
for(Iterator it = c.iterator();it.hasNext();) { Student s = (Student)it.next(); //向下转型 System.out.println(s.getName() + "," + s.getAge()); //获取对象中的姓名和年龄 } System.out.println("------------------------------"); Iterator it = c.iterator(); //获取迭代器 while(it.hasNext()) { //判断集合中是否有元素 Student s = (Student)it.next(); //向下转型 System.out.println(s.getName() + "," + s.getAge()); //获取对象中的姓名和年龄 } ```
7.迭代器的原理及源码解析
A:迭代器原理
迭代器原理:迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法,这样做是可以的,但是会让整个集合体系过于臃肿,迭代器是将这样的方法向上抽取出接口,然后在每个类的内部,定义自己迭代方式,这样做的好处有二,第一规定了整个集合体系的遍历方式都是hasNext()和next()方法,第二,代码有底层内部实现,使用者不用管怎么实现的,会用即可
B:迭代器源码解析
1,在eclipse中ctrl + shift + t找到ArrayList类
2,ctrl+o查找iterator()方法
3,查看返回值类型是new Itr(),说明Itr这个类实现Iterator接口
4,查找Itr这个内部类,发现重写了Iterator中的所有抽象方法
9.List集合的特有功能概述和测试
A:List集合的特有功能概述
void add(int index,E element)
E remove(int index)
E get(int index)
E set(int index,E element)
10.List集合存储学生对象并遍历
A:案例演示
通过size()和get()方法结合使用遍历。
```java
List list = new ArrayList(); list.add(new Student("张三", 18)); list.add(new Student("李四", 18)); list.add(new Student("王五", 18)); list.add(new Student("赵六", 18));
for(int i = 0; i < list.size(); i++) { Student s = (Student)list.get(i); System.out.println(s.getName() + "," + s.getAge()); } ```
11.并发修改异常产生的原因及解决方案
A:案例演示
需求:我有一个集合,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。
```java
List list = new ArrayList(); list.add("a"); list.add("b"); list.add("world"); list.add("d"); list.add("e");
/Iterator it = list.iterator(); while(it.hasNext()) { String str = (String)it.next(); if(str.equals("world")) { list.add("javaee"); //这里会抛出ConcurrentModificationException并发修改异常 } }/ ```
B:ConcurrentModificationException出现
迭代器遍历,集合修改集合
C:解决方案
a:迭代器迭代元素,迭代器修改元素(ListIterator的特有功能add)
b:集合遍历元素,集合修改元素
```java
ListIterator lit = list.listIterator(); //如果想在遍历的过程中添加元素,可以用ListIterator中的add方法
while(lit.hasNext()) {
String str = (String)lit.next();
if(str.equals("world")) {
lit.add("javaee");
//list.add("javaee");
}
}
```
12.ListIterator
boolean hasNext()是否有下一个
boolean hasPrevious()是否有前一个
Object next()返回下一个元素
Object previous();返回上一个元素
13. Vector的特有功能
A:Vector类概述
B:Vector类特有功能
public void addElement(E obj)
public E elementAt(int index)
public Enumeration elements()
C:案例演示
Vector的迭代
```java
Vector v = new Vector(); //创建集合对象,List的子类 v.addElement("a"); v.addElement("b"); v.addElement("c"); v.addElement("d");
//Vector迭代 Enumeration en = v.elements(); //获取枚举 while(en.hasMoreElements()) { //判断集合中是否有元素 System.out.println(en.nextElement());//获取集合中的元素 } ```
14.数据结构之数组和链表
A:数组
查询快修改也快
增删慢
B:链表
查询慢,修改也慢
增删快
15.List的三个子类的特点
A:List的三个子类的特点
ArrayList: 底层数据结构是数组,查询快,增删慢。 线程不安全,效率高。 Vector: 底层数据结构是数组,查询快,增删慢。 线程安全,效率低。 Vector相对ArrayList查询慢(线程安全的) Vector相对LinkedList增删慢(数组结构) LinkedList: 底层数据结构是链表,查询慢,增删快。 线程不安全,效率高。
powershell Vector 和 ArrayList 的区别 Vector 是线程安全的,效率低 ArrayList 是线程不安全的,效率高 共同点:都是数组实现的 ArrayList 和 LinkedList 的区别 ArrayList 底层是数组结果,查询和修改快 LinkedList 底层是链表结构的,增和删比较快,查询和修改比较慢 共同点:都是线程不安全的* B:List有三个儿子,我们到底使用谁呢? 查询多用ArrayList 增删多用LinkedList 如果都多ArrayList(一般都会经常使用ArrayList)
1.HashSet存储字符串并遍历)
A:Set集合概述及特点
通过API查看即可
B:案例演示
HashSet存储字符串并遍历
```java Set set = new HashSet<>();
set.add("lisi"); set.add("lisi"); set.add("wangwu"); set.add("wangw1u"); set.add("wang2w1u");
for (String string : set) { System.out.println(string); } ``` 将集合中的重复元素去掉
2.HashSet存储自定义对象
A:案例演示
存储自定义对象,并保证元素唯一性。
重写hashCode()和equals()方法
```java Set set = new HashSet<>(); Teacher t1 = new Teacher("lisi",13); Teacher t2 = new Teacher("lisi",13) Teacher t3 = new Teacher("lisi"13); /* * 先判断hashcode * hashcode不一致那么就不是同一个对象 * hashcode一致 * 那么久再去调用equals * true 对象一样 * false 不一样 */ set.add(t1); set.add(t2); set.add(t3);
for (Teacher teacher : set) { System.out.println(teacher); } ```
4.HashSet如何保证元素唯一性的原理
1.HashSet原理
我们使用Set集合都是需要去掉重复元素的, 如果在存储的时候逐个equals()比较, 效率较低,哈希算法提高了去重复的效率, 降低了使用equals()方法的次数
当HashSet调用add()方法存储对象的时候, 先调用对象的hashCode()方法得到一个哈希值, 然后在集合中查找是否有哈希值相同的对象
如果没有哈希值相同的对象就直接存入集合
如果有哈希值相同的对象, 就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入, true则不存
2.将自定义类的对象存入HashSet去重复
类中必须重写hashCode()和equals()方法
hashCode(): 属性相同的对象返回值必须相同, 属性不同的返回值尽量不同(提高效率)
equals(): 属性相同返回true, 属性不同返回false,返回false的时候存储
5.LinkedHashSet的概述和使用
A:LinkedHashSet的特点
B:案例演示
LinkedHashSet的特点
可以保证怎么存就怎么取
```java package corejava_day17.set;
import java.util.Iterator; import java.util.LinkedHashSet;
public class LinkedListed { public static void main(String[] args) { LinkedHashSet set = new LinkedHashSet(); set.add("lisi"); set.add("lisi2555"); set.add("lisi3"); set.add("lisi1"); set.add("lis64i");
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
```
6.产生10个1-20之间的随机数要求随机数不能重复
A:案例演示
需求:编写一个程序,获取10个1至20的随机数,要求随机数不能重复。并把最终的随机数输出到控制台。
```java package corejava_day17.set;
import java.util.HashSet; import java.util.Random; import java.util.Set;
public class LinkedListed { public static void main(String[] args) { Random random = new Random(); Set set = new HashSet<>(); while(set.size() < 20) { int number = random.nextInt(20) + 1; set.add(number); }
for (Integer integer : set) {
System.out.println(integer);
}
}
}
```
7.练习
使用Scanner从键盘读取一行输入,去掉其中重复字符, 打印出不同的那些
8.TreeSet存储Integer类型的元素并遍历
A:案例演示
TreeSet存储Integer类型的元素并遍历
9.TreeSet存储自定义对象
A:案例演示
存储Person对象
10.TreeSet保证元素唯一和自然排序的原理和图解
A:画图演示
TreeSet保证元素唯一和自然排序的原理和图解
```powershell 二叉树: 小的存储在左边,大的存储在右边 负数在左边 后一个比前一个小 正数在右边 后一个比前一个大 0代表集合中只有这样一个元素 每次先去根元素比较
按照年纪排序,年纪相同按照名字排序 ```
11.TreeSet存储自定义对象并遍历练习
A:案例演示
TreeSet存储自定义对象并遍历练习1(按照姓名排序)
12.TreeSet存储自定义对象并遍历练习2
A:案例演示
TreeSet存储自定义对象并遍历练习2(按照姓名的长度排序)
13.TreeSet保证元素唯一和比较器排序的原理及代码实现
A:案例演示
TreeSet保证元素唯一和比较器排序的原理及代码实现
```java // 按照字符串长度排序 package corejava_day17.set;
import java.util.Comparator; import java.util.TreeSet;
class Com implements Comparator {
// o2 代表集合中已经有的
// o1 新添加的
// 每次首先都会与根元素比计较
//负数在左边 后一个比前一个小
//正数在右边 后一个比前一个大
//0代表集合中只有这样一个元素
@Override
public int compare(String o1, String o2) {
int num = o1.length() - o2.length();
return num == 0 ? o1.compareTo(o2) : num;
}
}
public class LinkedListed { public static void main(String[] args) { TreeSet set = new TreeSet<>(new Com());
set.add("ddddddddd");
set.add("dd");
System.out.println(set.toString());
}
}
```
14.TreeSet原理
1.特点
TreeSet是用来排序的, 可以指定一个顺序, 对象存入之后会按照指定的顺序排列
2.使用方式
a.自然顺序(Comparable)
TreeSet类的add()方法中会把存入的对象提升为Comparable类型
调用对象的compareTo()方法和集合中的对象比较
根据compareTo()方法返回的结果进行存储
b.比较器顺序(Comparator)
创建TreeSet的时候可以制定 一个Comparator
如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的顺序排序
add()方法内部会自动调用Comparator接口中compare()方法排序
调用的对象是compare方法的第一个参数,集合中的对象是compare方法的第二个参数
c.两种方式的区别
TreeSet构造函数什么都不传, 默认按照类中Comparable的顺序(没有就报错ClassCastException)
TreeSet如果传入Comparator, 就优先按照Comparator
1.练习
在一个集合中存储了无序并且重复的字符串,定义一个方法,让其有序(字典顺序),而且还不能去除重复
```java package com.briup.test;
import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.TreeSet;
public class Test4 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("aaa");
list.add("aaa");
list.add("ccc");
list.add("ddd");
list.add("fffffffffff");
list.add("briup");
list.add("bbbb");
list.add("aaa");
list.add("aaa");
sort(list);
System.out.println(list);
}
public static void sort(List<String> list) {
TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
int num = s1.compareTo(s2); //比较内容为主要条件
return num == 0 ? 1 : num; //保留重复
}
});
//2,将list集合中所有的元素添加到TrreSet集合中,对其排序,保留重复
ts.addAll(list);
//3,清空list集合
list.clear();
//4,将TreeSet集合中排好序的元素添加到list中
list.addAll(ts);
}
}
```
从键盘接收一个字符串, 程序对其中所有字符进行排序,例如键盘输入: helloitcast程序打印:acehillostt(保留重复)
```java package com.briup.test;
import java.util.Comparator; import java.util.Scanner; import java.util.TreeSet;
public class Test5 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串");
String line = sc.nextLine();
char[] arr = line.toCharArray();
TreeSet<Character> ts = new TreeSet<>(new Comparator<Character>() {
@Override
public int compare(Character c1, Character c2) {
int num = c1.compareTo(c2);
return num == 0 ? 1 : num;
}
});
for(char c : arr) {
ts.add(c);
}
for(Character c : ts) {
System.out.print(c);
}
}
}
```
程序启动后, 可以从键盘输入接收多个整数, 直到输入quit时结束输入. 把所有输入的整数倒序排列打印.(保留重复的)
```java package com.briup.test;
import java.util.Comparator; import java.util.Scanner; import java.util.TreeSet;
public class Test6 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
TreeSet<Integer> ts = new TreeSet<>(new Comparator<Integer>() {
@Override
public int compare(Integer i1, Integer i2) {
int num = i2.compareTo(i1);
return num == 0 ? 1 : num;
}
});
while(true) {
String line = sc.nextLine();
if("quit".equals(line)) {
break;
}
Integer i = Integer.parseInt(line);
ts.add(i);
}
for (Integer integer : ts) {
System.out.println(integer);
}
}
}
```
键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台。(分数相同按照名字排序)