1 ArrayList 的 toString()方法
Collection c = new ArrayList();
ArrayList 的 toString()方法被重写过
System.out.println(c);
输出时 输出的是ArrayList的toString();
2 Set
Collection
---List:有序(存储顺序和取出顺序一致),可重复
---Set:无序(存储顺序和取出顺序不一致),唯一
HashSet:它不保证set的迭代顺序:特别是它不保证该顺序恒久不变
注意:虽然Set集合的元素无序,但是,作为集合来说,它肯定有自己的存储顺序。而你的顺序恰好和它的存储顺序一致,这代表不了有序,可以多测试一些。
Set<String> set =new HashSet<String>();
set.add("hello");
set.add("world");
set.add("java");
set.add("world");
set.add("java");
for(String s: set){
System.out.println(s);
}
//输出: hello
java
world
3 HashSet 元素的唯一性
为什么存储字符串的时候,字符串内容相同的只存储了一个呢?
通过查看add方法的源码,我们知道这个方法底层依赖两个方法:hashCode()和equals()。
步骤:
首先比较哈希值
如果相同,继续走,比较地址值或者走equals
如果不同,就直接加到集合中
按照方法的步骤来说:
先看hashCode()值是否相同
相同:继续走equals()方法
返回true:说明元素重复,就不添加
返回false,说明元素不重复,就添加到集合
不同:就直接把元素添加到集合
如果类没有重写这两个方法,默认使用的Object()。
而String类重写了hashCode()和equals()方法,所以,它就可以把内容相同的字符串去掉,只留下一个。
---------------------------------
HashSet
A:底层数据结构是哈希表(是一个元素为链表的数组)
B:哈希表底层依赖两个方法:hashCode()和equals()
执行顺序:
首先比较哈希值是否相同
相同:继续执行equals()方法
返回true:元素重复了,不添加
返回false:直接把元素添加到集合
不同:就直接把元素添加到集合
C:如何保证元素唯一性的呢?
由hashCode()和equals()保证的
4 HashSet 的练习
HashSet集合存储自定义对象并遍历,如果对象的成员变量相同即为同一个对象。
注意了:
你使用的是HashSet集合,这个集合的底层是哈希表结构
而哈希表结构底层依赖:hashCode()和equals()方法。
如果你认为对象的成员变量值即为同一个对象的话,你就应该重写这两个方法。
如何重写这两个方法呢? 自动生成即可!
//创建集合对象
HashSet<Dog> hs = new HashSet<Dog>();
//创建狗对象
Dog d1 = new Dog("黄狗",5,"黄色");
Dog d2 = new Dog("黄狗",5,"黄色");
Dog d3 = new Dog("白狗",6,"白色");
Dog d4 = new Dog("黑狗",7,"黑色");
//添加元素
hs.add(d1);
hs.add(d2);
hs.add(d3);
hs.add(d4);
//遍历
for(Dog d:hs ){
System.out.println(d.getName()+"---"+d.getAge()+"---"d.getColor());
}
//输出: 黄狗---5---黄色
黄狗---5---黄色
白狗---6---白色
黑狗---7---黑色
5 LinkedHashSet
底层:数据结构由哈希表和链表组成
哈希表保证元素的唯一性
链表保证元素有序(存储和取出时一致的)
LinkedHashSet<String> hs =new LinkedHashSet<String>();
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("world");
hs.add("java");
for(String s: hs){
System.out.println(s);
}
//输出: hello
world
java
6 TreeSet
(1) 能够对元素按照某种规则进行排序
A:自然排序
B: 比较器排序
***TreeSet集合的特点:排序和唯一
//创建集合对象
//自然顺序进行排序
TreeSet<Integer> ts = new TreeSet<Integer>();
//创建元素并添加
//20,18,23,22
ts.add(20);
ts.add(18);
ts.add(23);
ts.add(22);
ts.add(18);
//遍历
for(Integer i:ts){
System.out.println(i);
}
//输出:18
20
22
23
(2) 底层是二叉树结构(红黑树是一种自平衡的二叉树)
元素是如何存储进去的呢?
第一个元素存储的时候,直接作为根节点存储
从第二个元素开始,每个元素从根节点开始比较
大 就作为右孩子
小 就作为左孩子
相等 就不搭理它
那又是怎么取出来的呢?
前序遍历
从根节点开始,按照左,中,右的原则依次取出元素即可
(3) 练习:TreeSet存储自定义对象并保证排序和唯一
A:你没有告诉我们怎么排序
自然排序,按照年龄从小到大排序
B:元素什么情况下唯一你也没有告诉我
成员变量值都相同即为同一个元素
-----------------------------------------
......
@Ovrride
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;
//如果 num == 0(年龄相同),就接着比姓名,否则返回年龄
return num2;
}
------------------------------------------
//创建集合对象
TreeSet<Student> ts = new TreeSet<Student>();
//创建元素
Student s1 = new Student("nihao",27);
Student s2 = new Student("hello",26);
Student s3 = new Student("world",28);
Student s4 = new Student("java",20);
Student s5 = new Student("javaee",20);
//添加元素
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());
}
//输出: java---20
javaee---20
hello---26
nihao---27
world---28
7 TreeSet 两种排序
(1) 自然排序
让存储的元素所属的那个类实现Comparable接口
TreeSet<Student> ts = new TreeSet<Student>();//自然排序
(2) 比较器排序
让集合构造方法接收Comparator的实现类对象
public TreeSet(Comparator comparator); //比较器比较
TreeSet<Student> ts = new TreeSet<Student>(new MyComparator());
---------------------------------------------------
public class MyComparator implements Comparator<Student>{
@Override
public int compare(Student s1,Student s2){
//姓名长度
int num = s1.getNmae().length() - s2.getNmae().length()
//姓名内容
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()): num;
//年龄
int num3 = num2 == 0 ? s1.getAge() - s2 .getAge() :num2;
return num3;
}
}
----------------------------------------------------
//如果一个方法的参数是接口,那么真正要的是接口实现类的对象
//匿名内部类就可以实现这个东西
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>()
@Override
public int compare(Student s1,Student s2){
//姓名长度
int num = s1.getNmae().length() - s2.getNmae().length()
//姓名内容
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()): num;
//年龄
int num3 = num2 == 0 ? s1.getAge() - s2 .getAge() :num2;
return num3;
});
8 TreeSet
TreeSet集合保证元素排序和唯一性的原理
(1)唯一性:根据比较的返回值是否是0来决定
(2)排序
A:自然排序(元素具备比较性)
让元素所属的类实现自然排序接口 Comparable
B:比较器排序(集合具备比较性)
让集合的构造方法接收一个比较器接口的子类对象 Comparator
9 获取10个1至20的随机数,要求随机数不能重复
//创建随机数对象
Random r = new Random();
//创建一个Set集合
HashSet<Integer> ts = new HashSet<Integer>();
//判断集合的长度是不是小于10
while(ts.size() < 10){
int num = r.nextInt(20)+1;
ts.add(num);
}
//遍历Set集合
for(Integer i : ts){
System.out.println(i);
}
Collection c = new ArrayList();
ArrayList 的 toString()方法被重写过
System.out.println(c);
输出时 输出的是ArrayList的toString();
2 Set
Collection
---List:有序(存储顺序和取出顺序一致),可重复
---Set:无序(存储顺序和取出顺序不一致),唯一
HashSet:它不保证set的迭代顺序:特别是它不保证该顺序恒久不变
注意:虽然Set集合的元素无序,但是,作为集合来说,它肯定有自己的存储顺序。而你的顺序恰好和它的存储顺序一致,这代表不了有序,可以多测试一些。
Set<String> set =new HashSet<String>();
set.add("hello");
set.add("world");
set.add("java");
set.add("world");
set.add("java");
for(String s: set){
System.out.println(s);
}
//输出: hello
java
world
3 HashSet 元素的唯一性
为什么存储字符串的时候,字符串内容相同的只存储了一个呢?
通过查看add方法的源码,我们知道这个方法底层依赖两个方法:hashCode()和equals()。
步骤:
首先比较哈希值
如果相同,继续走,比较地址值或者走equals
如果不同,就直接加到集合中
按照方法的步骤来说:
先看hashCode()值是否相同
相同:继续走equals()方法
返回true:说明元素重复,就不添加
返回false,说明元素不重复,就添加到集合
不同:就直接把元素添加到集合
如果类没有重写这两个方法,默认使用的Object()。
而String类重写了hashCode()和equals()方法,所以,它就可以把内容相同的字符串去掉,只留下一个。
---------------------------------
HashSet
A:底层数据结构是哈希表(是一个元素为链表的数组)
B:哈希表底层依赖两个方法:hashCode()和equals()
执行顺序:
首先比较哈希值是否相同
相同:继续执行equals()方法
返回true:元素重复了,不添加
返回false:直接把元素添加到集合
不同:就直接把元素添加到集合
C:如何保证元素唯一性的呢?
由hashCode()和equals()保证的
4 HashSet 的练习
HashSet集合存储自定义对象并遍历,如果对象的成员变量相同即为同一个对象。
注意了:
你使用的是HashSet集合,这个集合的底层是哈希表结构
而哈希表结构底层依赖:hashCode()和equals()方法。
如果你认为对象的成员变量值即为同一个对象的话,你就应该重写这两个方法。
如何重写这两个方法呢? 自动生成即可!
//创建集合对象
HashSet<Dog> hs = new HashSet<Dog>();
//创建狗对象
Dog d1 = new Dog("黄狗",5,"黄色");
Dog d2 = new Dog("黄狗",5,"黄色");
Dog d3 = new Dog("白狗",6,"白色");
Dog d4 = new Dog("黑狗",7,"黑色");
//添加元素
hs.add(d1);
hs.add(d2);
hs.add(d3);
hs.add(d4);
//遍历
for(Dog d:hs ){
System.out.println(d.getName()+"---"+d.getAge()+"---"d.getColor());
}
//输出: 黄狗---5---黄色
黄狗---5---黄色
白狗---6---白色
黑狗---7---黑色
5 LinkedHashSet
底层:数据结构由哈希表和链表组成
哈希表保证元素的唯一性
链表保证元素有序(存储和取出时一致的)
LinkedHashSet<String> hs =new LinkedHashSet<String>();
hs.add("hello");
hs.add("world");
hs.add("java");
hs.add("world");
hs.add("java");
for(String s: hs){
System.out.println(s);
}
//输出: hello
world
java
6 TreeSet
(1) 能够对元素按照某种规则进行排序
A:自然排序
B: 比较器排序
***TreeSet集合的特点:排序和唯一
//创建集合对象
//自然顺序进行排序
TreeSet<Integer> ts = new TreeSet<Integer>();
//创建元素并添加
//20,18,23,22
ts.add(20);
ts.add(18);
ts.add(23);
ts.add(22);
ts.add(18);
//遍历
for(Integer i:ts){
System.out.println(i);
}
//输出:18
20
22
23
(2) 底层是二叉树结构(红黑树是一种自平衡的二叉树)
元素是如何存储进去的呢?
第一个元素存储的时候,直接作为根节点存储
从第二个元素开始,每个元素从根节点开始比较
大 就作为右孩子
小 就作为左孩子
相等 就不搭理它
那又是怎么取出来的呢?
前序遍历
从根节点开始,按照左,中,右的原则依次取出元素即可
(3) 练习:TreeSet存储自定义对象并保证排序和唯一
A:你没有告诉我们怎么排序
自然排序,按照年龄从小到大排序
B:元素什么情况下唯一你也没有告诉我
成员变量值都相同即为同一个元素
-----------------------------------------
如果一个类的元素要想能够进行自然排序,就必须实现自然排序接口
即类要实现Comparable接口,并重写compareTo()方法,TreeSet对象调用add()方法时,会将存入的对象提升为Comparable类型,然后调用对象中的compareTo()方法进行比较,根据比较的返回值进行存储。
-----http://blog.csdn.net/StriverLi/article/details/56669973
------------------------------------------------------------------
public class Student implements Comparable<Student>{......
@Ovrride
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;
//如果 num == 0(年龄相同),就接着比姓名,否则返回年龄
return num2;
}
------------------------------------------
//创建集合对象
TreeSet<Student> ts = new TreeSet<Student>();
//创建元素
Student s1 = new Student("nihao",27);
Student s2 = new Student("hello",26);
Student s3 = new Student("world",28);
Student s4 = new Student("java",20);
Student s5 = new Student("javaee",20);
//添加元素
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());
}
//输出: java---20
javaee---20
hello---26
nihao---27
world---28
7 TreeSet 两种排序
(1) 自然排序
让存储的元素所属的那个类实现Comparable接口
TreeSet<Student> ts = new TreeSet<Student>();//自然排序
(2) 比较器排序
让集合构造方法接收Comparator的实现类对象
public TreeSet(Comparator comparator); //比较器比较
TreeSet<Student> ts = new TreeSet<Student>(new MyComparator());
---------------------------------------------------
public class MyComparator implements Comparator<Student>{
@Override
public int compare(Student s1,Student s2){
//姓名长度
int num = s1.getNmae().length() - s2.getNmae().length()
//姓名内容
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()): num;
//年龄
int num3 = num2 == 0 ? s1.getAge() - s2 .getAge() :num2;
return num3;
}
}
----------------------------------------------------
//如果一个方法的参数是接口,那么真正要的是接口实现类的对象
//匿名内部类就可以实现这个东西
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>()
@Override
public int compare(Student s1,Student s2){
//姓名长度
int num = s1.getNmae().length() - s2.getNmae().length()
//姓名内容
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()): num;
//年龄
int num3 = num2 == 0 ? s1.getAge() - s2 .getAge() :num2;
return num3;
});
8 TreeSet
TreeSet集合保证元素排序和唯一性的原理
(1)唯一性:根据比较的返回值是否是0来决定
(2)排序
A:自然排序(元素具备比较性)
让元素所属的类实现自然排序接口 Comparable
B:比较器排序(集合具备比较性)
让集合的构造方法接收一个比较器接口的子类对象 Comparator
9 获取10个1至20的随机数,要求随机数不能重复
//创建随机数对象
Random r = new Random();
//创建一个Set集合
HashSet<Integer> ts = new HashSet<Integer>();
//判断集合的长度是不是小于10
while(ts.size() < 10){
int num = r.nextInt(20)+1;
ts.add(num);
}
//遍历Set集合
for(Integer i : ts){
System.out.println(i);
}