代码:
Collection c = new ArrayList();
c.add("hello");
c.add("world");
c.add("java");
System.out.println(c);
为什么c输出的不是地址值呢?
A:Collection c = new ArrayList();
这是多态,所以输出c的toString()方法,其实是输出ArrayList的toString()
B:看ArrayList的toString()
而我们在ArrayList里面却没有发现toString()。
以后遇到这种情况,也不要担心,你认为有,它却没有,就应该去它父亲里面看看。
C:toString()的方法源码
public String toString() {
Iterator<E> it = iterator(); //集合本身调用迭代器方法,得到集合迭代器
if (! it.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
E e = it.next(); //e=hello,world,java
sb.append(e == this ? "(this Collection)" : e);this是地址值不可能与相等。
if (! it.hasNext())
//[hello, world, java]
return sb.append(']').toString();
sb.append(',').append(' ');
}
}
1:登录注册案例(理解)
需求:用户登录注册案例。
按照如下的操作,可以让我们更符号面向对象思想
A:有哪些类呢?
B:每个类有哪些东西呢?
C:类与类之间的关系是什么呢?
分析:
A:有哪些类呢?
用户类
测试类
B:每个类有哪些东西呢?
用户类:
成员变量:用户名,密码
构造方法:无参构造
成员方法:getXxx()/setXxx()
登录,注册
假如用户类的内容比较对,将来维护起来就比较麻烦,为了更清晰的分类,我们就把用户又划分成了两类
用户基本描述类
成员变量:用户名,密码
构造方法:无参构造
成员方法:getXxx()/setXxx()
用户操作类
登录,注册
测试类:
main方法。
C:类与类之间的关系是什么呢?
在测试类中创建用户操作类和用户基本描述类的对象,并使用其功能。
分包:
A:功能划分
B:模块划分
C:先按模块划分,再按功能划分
今天我们选择按照功能划分:
用户基本描述类包 cn.itcast.pojo
用户操作接口 cn.itcast.dao
用户操作类包 cn.itcast.dao.impl
今天是集合实现,过几天是IO实现,再过几天是GUI实现,就业班我们就是数据库实现
用户测试类 cn.itcast.test
2:Set集合(理解)
(1)Set集合的特点
无序,唯一
Collection
* |--List
* 有序(存储顺序和取出顺序一致),可重复
* |--Set
* 无序(存储顺序和取出顺序不一致),唯一
*
* HashSet:它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。
* 注意:虽然Set集合的元素无序,但是,作为集合来说,它肯定有它自己的存储顺序,
* 而你的顺序恰好和它的存储顺序一致,这代表不了有序,你可以多存储一些数据,就能看到效果。
*/public class SetDemo {
public static void main(String[] args) {
// 创建集合对象
Set<String> set = new HashSet<String>();
// 创建并添加元素
set.add("hello");
set.add("java");
set.add("world");
set.add("java");
set.add("world");
// 增强for
for (String s : set) {
System.out.println(s);
}
}
}
(2)HashSet集合(掌握)
- A:底层数据结构是哈希表(是一个元素为链表的数组)
- B:哈希表底层依赖两个方法:hashCode()和equals()
执行顺序:
首先比较哈希值是否相同
相同:继续执行equals()方法
返回true:元素重复了,不添加
返回false:直接把元素添加到集合
不同:就直接把元素添加到集合
如果类没有重写这两个方法,默认使用的Object()。一般来说不同相同。
* 而String类重写了hashCode()和equals()方法,所以,它就可以把内容相同的字符串去掉。只留下一个。
C:如何保证元素唯一性的呢?
由hashCode()和equals()保证的
D:开发的时候,代码非常的简单,自动生成即可。
E:HashSet存储字符串并遍历
F:HashSet存储自定义对象并遍历(对象的成员变量值相同即为同一个元素)
* LinkedHashSet:底层数据结构由哈希表和链表组成。
* 哈希表保证元素的唯一性。
* 链表保证元素有素。(存储和取出是一致)
*/
public class LinkedHashSetDemo {
public static void main(String[] args) {
// 创建集合对象
LinkedHashSet<String> hs = new LinkedHashSet<String>();
// 创建并添加元素
add("hello");
add("world");
add("java");
add("world");
add("java");
// 遍历
for (String s : hs) {
out.println(s);
}
}
}
(3)TreeSet集合
A:底层数据结构是红黑树(是一个自平衡的二叉树)
B:保证元素的排序方式
a:自然排序(元素具备比较性)// Comparable自然排序接口
- 让元素所属的类实现Comparable接口
b:比较器排序(集合具备比较性)
让集合构造方法接收Comparator的实现类对象
C:把我们讲过的代码看一遍即可
* TreeSet存储自定义对象并保证排序和唯一。
*
* A:你没有告诉我们怎么排序
* 自然排序,按照年龄从小到大排序
* B:元素什么情况算唯一你也没告诉我
* 成员变量值都相同即为同一个元素
自定义对象自然排序代码实现
*/
public class TreeSetDemo2 {
public static void main(String[] args) {
// 创建集合对象
TreeSet<Student> ts = new TreeSet<Student>();
// 创建元素
Student s1 = new Student("linqingxia", 27);
Student s2=new Student("zhangguong", 29);
Student s3 = new Student("wanglihong", 23);
Student s4 = new Student("linqingxia", 27);
Student s5 = new Student("liushishi", 22);
Student s6 = new Student("wuqilong", 40);
Student s7 = new Student("fengqingy", 22);
// 添加元素
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
ts.add(s6);
ts.add(s7);
// 遍历
for (Student s : ts) {
System.out.println(s.getName() + "---" + s.getAge());
}
}
}
/*
* 如果一个类的元素要想能够进行自然排序,就必须实现自然排序接口
*/
public class Student implements Comparable<Student> {
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
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;
// return 1;
// return -1;
// 这里返回什么,其实应该根据我的排序规则来做
// 按照年龄排序,主要条件
int num = this.age - s.age;
// 次要条件
// 年龄相同的时候,还得去看姓名是否也相同
// 如果年龄和姓名都相同,才是同一个元素
int num2 = num == 0 ? this.name.compareTo(s.name) : num;
return num2;
}
}
比较器比较代码实现
/*
* 需求:请按照姓名的长度排序
*
* TreeSet集合保证元素排序和唯一性的原理
* 唯一性:是根据比较的返回是否是0来决定。
* 排序:
* A:自然排序(元素具备比较性)
* 让元素所属的类实现自然排序接口 Comparable
* B:比较器排序(集合具备比较性)
* 让集合的构造方法接收一个比较器接口的子类对象 Comparator
*/
public class TreeSetDemo {
public static void main(String[] args) {
// 创建集合对象
// TreeSet<Student> ts = new TreeSet<Student>(); //自然排序
// public TreeSet(Comparator comparator) //比较器排序
//如果这样的话需要写一个MyComparator
// TreeSet<Student> ts = new TreeSet<Student>(new MyComparator());
// 如果一个方法的参数是接口,那么真正要的是接口的实现类的对象
// 而匿名内部类就可以实现这个东西//如果你只是为了比较一次
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
// 姓名长度
int num = s1.getName().length() - s2.getName().length();
// 姓名内容
int num2 = num == 0 ? s1.getName().compareTo(s2.getName())
: num;
// 年龄
int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
return num3;
}
});
// 创建元素
Student s1 = new Student("linqingxia", 27);
Student s2 = new Student("zhangguorong", 29);
Student s3 = new Student("wanglihong", 23);
Student s4 = new Student("linqingxia", 27);
Student s5 = new Student("liushishi", 22);
Student s6 = new Student("wuqilong", 40);
Student s7 = new Student("fengqingy", 22);
Student s8 = new Student("linqingxia", 29);
// 添加元素
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.getAge());
}
}
}
- //这是MyComparator实现类
-
获取无重复的随机数public class MyComparator implements Comparator<Student> { @Override public int compare(Student s1, Student s2) { // int num = this.name.length() - s.name.length(); // this -- s1 // s -- s2 // 姓名长度 int num = s1.getName().length() - s2.getName().length(); // 姓名内容 int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; // 年龄 int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2; return num3; } (4)案例: A:
public class TreeSetDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
TreeSet<Integer> ts=new TreeSet<Integer>();
Random r=new Random();
while(ts.size()<10){
int rom=r.nextInt(20)+1;
ts.add(rom);
}
for(Integer i: ts){
System.out.println(i);
}
}
}
- B:键盘录入学生按照总分从高到底输出
public class TreeSetDemo {
public static void main(String[] args) {
// 创建一个TreeSet集合
TreeSet<Student> ts = new TreeSet<Student>(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.getMath() - s2.getMath() : num2;
// 总分相同的不一定英语相同
int num4 = num3 == 0 ? s1.getEnglish() - s2.getEnglish() : num3;
// 姓名还不一定相同呢
int num5 = num4 == 0 ? s1.getName().compareTo(s2.getName())
: num4;
return num5;
}
});
System.out.println("学生信息录入开始");
// 键盘录入5个学生信息
for (int x = 1; x <= 5; x++) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入第" + x + "个学生的姓名:");
String name = sc.nextLine();
System.out.println("请输入第" + x + "个学生的语文成绩:");
String chineseString = sc.nextLine();
System.out.println("请输入第" + x + "个学生的数学成绩:");
String mathString = sc.nextLine();
System.out.println("请输入第" + x + "个学生的英语成绩:");
String englishString = sc.nextLine();
// 把数据封装到学生对象中
Student s = new Student();
s.setName(name);
s.setChinese(Integer.parseInt(chineseString));
s.setMath(Integer.parseInt(mathString));
s.setEnglish(Integer.parseInt(englishString));
// 把学生对象添加到集合
ts.add(s);
}
System.out.println("学生信息录入完毕");
System.out.println("学习信息从高到低排序如下:");
System.out.println("姓名\t语文成绩\t数学成绩\t英语成绩");
// 遍历集合
for (Student s : ts) {
System.out.println(s.getName() + "\t" + s.getChinese() + "\t"
+ s.getMath() + "\t" + s.getEnglish());
}
}
}
3:Collection集合总结(掌握)
Collection
|--List 有序,可重复
|--ArrayList
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高
|--Vector
底层数据结构是数组,查询快,增删慢。
线程安全,效率低
|--LinkedList
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高
|--Set 无序,唯一
|--HashSet
底层数据结构是哈希表。
如何保证元素唯一性的呢?
依赖两个方法:hashCode()和equals()
开发中自动生成这两个方法即可
|--LinkedHashSet
底层数据结构是链表和哈希表
由链表保证元素有序
由哈希表保证元素唯一
|--TreeSet
底层数据结构是红黑树。
如何保证元素排序的呢?
自然排序
比较器排序
如何保证元素唯一性的呢?
根据比较的返回值是否是0来决定
4:针对Collection集合我们到底使用谁呢?(掌握)
唯一吗?
是:Set
排序吗?
是:TreeSet
否:HashSet
如果你知道是Set,但是不知道是哪个Set,就用HashSet。
否:List
要安全吗?
是:Vector
否:ArrayList或者LinkedList
查询多:ArrayList
增删多:LinkedList
如果你知道是List,但是不知道是哪个List,就用ArrayList。
如果你知道是Collection集合,但是不知道使用谁,就用ArrayList。
如果你知道用集合,就用ArrayList。
5:在集合中常见的数据结构(掌握)
ArrayXxx:底层数据结构是数组,查询快,增删慢
LinkedXxx:底层数据结构是链表,查询慢,增删快
HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals()
TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序