疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java编程Object知识和Set集合和Map比较


 

集合预备知识
 
一.Object类的三个方法
 
1.toString()对象的自我描述、自我介绍
 
目的简化getter输出
 
public String toString(){
 
return 对象的实例变量;
 
}
 
Student.java
 
不重写toString() 时 默认打印格式如下
 
类全名@hashCode
 
System.out.println(s);
 
相当于
 
System.out.println(s.toString());
 
2.equals()
 
复习==和equals:
 
String的两种创建方式 以及比较
 
public boolean equals(Object o){
 
//1.类型相同 instanceof 或反射判断
 
//2.定义自己的规则
 
}
 
重写equals一定要重写hashCode()
 
3.hashCode 用于加速查找 实质索引
 
public int hashCode(){
 
return ;
 
}
 
hashCode的两个基本原则
 
1.两个对象equals方法比较返回true,那么它俩的hashCode方法也要保证是相同
 
2.对象中用作equals比较标准的属性,都应该用来计算hashCode 每种类型的hashCode计算方式参见 疯狂java P250
 
二.一个原理 Hash算法 文件夹里找音乐的例子
 
查找算法、存储算法
 
歌名 按歌手分 苏打绿 苏打绿命名的文件夹
 
键 hash算法 hashCode 哈希马桶
 
对象存储
 
在存储时,为了加速查询,存储的时候就要按照对象的HashCode,存到对应的哈希马桶中(文件夹)
 
对象查找
 
用hash算法找对象,分两步
 
1.通过对象的hashCode找到所对应的哈希马桶(类似通过歌手名找到文件夹)
 
2.通过equals在桶里找对象
 
比较好的hash算法会保证尽量让一个哈希马桶里只有一个对象。
 
equals相等hashCode一定相等 (hashCode是文件夹 equals是歌)
 
hashCode相等equals不一定相等
 
 
*********************正式进入集合****************************
 
重点: 一个图 两个比较接口 三个迭代方法
 
一个图
 
集合设计思想
 
根据ordered(有迭代顺序)、sorted(有排序顺序)设计
 
Collection接口
 
Set接口 List接口 Queue接口
 
排序工具 单独的接口 Map
 
Object
 
--Arrays
 
--Collections
 
List 接口
 
Vector ArrayList LinkedList
 
--ArrayList 最常用 线性表的顺序存储方式 查找对象比较快,插入删除对象时比较慢。
 
1.动态数组(长度可变的数组) 10----->15--->22--->33
 
2.引用类型数组 里面的元素都是引用类型
 
3.有迭代顺序 迭代顺序为数组下标顺序
 
ArrayList 增删改查
 
--Vector(线程安全的ArrayList)
 
--LinkedList(链式数组) 线性表的链式存储方式 迭代顺序为链表的插入顺序 ,链表插入删除方便,查找慢
 
顺带讲解泛型
 
1.规范添加到集合的对象的类型,只能为一种
 
2.泛型是编译时检查
 
演示代码:
 
public class TestFanXing {
 
public static void main(String[] args) {
 
List<String> list = new ArrayList<String>();
 
Object obj = new Integer(1);
 
list.add((String)obj);
 
}
 
}
 
Set集合
 
HashSet SortedSet(接口)
 
LinkedHashSet NavigableSet(接口)
 
TreeSet
 
--HashSet
 
1.去重 案例:比如呼叫中心,对打入电话的客户去重,如果有100个用户,每个用户打了10遍,按电话号码去重,否则在回拨的时候就会打一百遍电话。
 
面试题:
 
对HashSet集合去重的标准:
 
hashCode() 和equals() 必须都相同,才是意义上相同的对象,就不能将象添加到集合中去,并把相同的对象去掉。只要hashCode()和equals()有一个不相同,那么他两不是相同的对象,就能添加进去。
 
2.无迭代顺序:所谓的迭代顺序就是输出顺序和添加顺序是不是一致。
 
额外知识(可以不管):实质输出顺序是根据一定算法求出来的 该算法和hashCode有些关系(可阅读源码并结合打断点查看)
 
--LinkedHashSet
 
有迭代顺序的HashSet 迭代顺序是链表中 元素的添加顺序
 
面试题:
 
HashSet 和LinkedHashSet如何选用?
 
不要求输出顺序和插入顺序一致时,使用HashSet
 
要求输出顺序和插入顺序一致时,使用LinkedHashSet
 
性能考虑
 
频繁插入数据时,用HashSet 因为LinkedHashSet要维护指针域 所以它比HashSet稍慢
 
主要为了迭代时 使用LinkedHashSet 比较快 因为有指针 遍历完第一个明确知道下一个元素的地址。
--TreeSet
 
1.有排序顺序的set,放入该set的对象必须实现Comparable接口的compareTo方法来定义排序规则。
 
2.在没有重写对象的equals()方法使用compareTo去重,compareTo 为0 表示重复的对象,会去掉,并不会吧对象添加到集合中去。
 
3.重写放入TreeSet的对象的equals()方法时,要保证equals为true时,compareTo为0,才能认为他们是同一个对象。
 
Map接口
 
Hashtable HashMap SortedMap(接口)
 
LinkedHashMap NavigableMap(接口)
 
TreeMap
 
一一对应 键值对 映射关系(实质是关联数组)
 
--HashMap 详解
 
1.通过hashCode、equals方法来判断两个键是否相同,可以举科目和成绩的例子
 
2.相同的key key不变 value覆盖
 
3.没有排序顺序也没有迭代顺序的Map,允许有一个key键为null和多个value值为null
 
--LinkedHashMap(有迭代顺序的HashMap)
 
--Hashtable 线程安全版本的HashMap(区别1),Hashtable不允许有任何为null的内容(区别2)
 
TreeMap(有排序顺序的Map)
 
也是使用compareTo 来确定同一个key,判断是否为相同的对象和上面TreeSet的集合相同。
 
*******************************************************************************
 
Collections和Arrays工具类
 
Collections、Arrays工具类 用于对集合和数组的排序
 
Collections.sort(list,排序规则对象);//只能排序List 不能排序Set
 
Arrays.sort(arr,排序规则对象);//排序数组
 
******************************两个比较接口************************************
 
--Comparable
 
TreeSet、TreeMap 中的对象的类必须实现Comparable接口的compareTo()方法
 
public class A implements Comparable<A>{
 
public int compareTo(A a){
 
//自定义排序规则
 
//如何实现:一般调用底层属性的compareTo方法 例如DVD的id的compareTo
 
return 数字;//整数,表示大,0表示相等、负数表示小
 
}
 
}
 
演示代码:参见DVD
 
--Comparator 排序规则接口 更加灵活 独立于DVD 最后使用collections.sort();调用
 
//排序规则
 
public class SortedDVDByPrice implements Comparator{
 
public int compare(Object o1, Object o2) {
 
DVD dvd1 = (DVD)o1;
 
DVD dvd2 = (DVD)o2;
 
Integer dvd1Price = dvd1.getPrice();
 
Integer dvd2Price = dvd2.getPrice();
 
return dvd1Price.compareTo(dvd2Price);
 
}
 
}
 
public int compareTo(A a){
 
//自定义排序规则
 
//如何实现:一般调用底层属性的compareTo方法 例如DVD的id的compareTo
 
return 数字;//整数,表示大,0表示相等、负数表示小
 
}
 
public class TestComparator {
 
public static void main(String[] args) {
 
List<DVD> list = new ArrayList<DVD>();
 
//Set<DVD> list = new HashSet<DVD>();
 
//实现按价格排序
 
DVD dvd1 = new DVD(3,"逆世界",30);
 
DVD dvd2 = new DVD(1,"北京爱上西雅图",20);
 
DVD dvd3 = new DVD(2,"叶问终极一战",10);
 
DVD dvd4 = new DVD(4,"北京爱上西雅图",20);
 
list.add(dvd1);
 
list.add(dvd2);
 
list.add(dvd3);
 
list.add(dvd4);
 
//另一个排序工具 Collections 工具类 提供排序功能
 
//没排序之前
 
for(DVD dvd:list){
 
System.out.println(dvd);
 
}
 
SortedDVDByPrice sortedDVDByPrice = new SortedDVDByPrice();
 
Collections.sort(list,sortedDVDByPrice);
 
//排序之后
 
System.out.println("排序之后");
 
for(DVD dvd:list){
 
System.out.println(dvd);
 
}
 
}
 
}
 
遍历Collection三种方式
 
1.Iterator接口
 
2.foreach
 
3.List可以通过size() 遍历
 
小技巧:直接输出集合引用名也可以查看元素 因为集合类重写了toString()方法