Collections.Sort()分为两部分,一部分为排序规则;一部分为排序算法。 规则用来判断对象;算法是考虑如何排序。
对于自定义对象,Sort不知道规则,所以无法比较。这种情况下一定要定义排序规则。方式有两种: ① java.lang下面有一个接口:Comparable(可比较的)
可以让自定义对象实现一个接口,这个接口只有一个方法comparableTo(Object o) 其规则是当前对象与o对象进行比较,其返回一个int值,系统根据此值来进行排序。 如 当前对象>o对象,则返回值>0;(可将返回值定义为1) 如 当前对象=o对象,则返回值=0; 如 当前对象 我们通过返回值1和-1位置的调换来实现升序和降序排列的转换。 ② java.util下有一个Comparator(比较器) 它拥有compare(),用来比较两个方法。 要生成比较器,则用Sort中Sort(List,List(Compate)) 第二种方法更灵活,且在运行的时候不用编译。 注意:要想实现comparTo()就必须在主方法中写上implement comparable. 练习:生成一个EMPLOYEE类,然后将一系列对象放入到ArrayList。用Iterator遍历,排序之后,再进行遍历。 集合的最大缺点是无法进行类型判定(这个缺点在JAVA1.5中已经解决),这样就可能出现因为类型不同而出现类型错误。 解决的方法是添加类型的判断。 LinkedList接口(在代码的使用过程中和ArrayList没有什么区别) ArrayList底层是object数组,所以ArrayList具有数组的查询速度快的优点以及增删速度慢的缺点。 而在LinkedList的底层是一种双向循环链表。在此链表上每一个数据节点都由三部分组成:前指针(指向前面的节点的位置),数据,后指针(指向后面的节点的位置)。最后一个节点的后指针指向第一个节点的前指针,形成一个循环。 双向循环链表的查询效率低但是增删效率高。所以LinkedList具有查询效率低但增删效率高的特点。 ArrayList和LinkedList在用法上没有区别,但是在功能上还是有区别的。 LinkedList经常用在增删操作较多而查询操作很少的情况下:队列和堆栈。 队列:先进先出的数据结构。 堆栈:后进先出的数据结构。 注意:使用堆栈的时候一定不能提供方法让不是最后一个元素的元素获得出栈的机会。 LinkedList提供以下方法:(ArrayList无此类方法) addFirst(); removeFirst(); addLast(); removeLast(); 在堆栈中,push为入栈操作,pop为出栈操作。 Push用addFirst();pop用removeFirst(),实现后进先出。 用isEmpty()--其父类的方法,来判断栈是否为空。 在队列中,put为入队列操作,get为出队列操作。 Put用addFirst(),get用removeLast()实现队列。 达内java学习笔记 16 List接口的实现类(Vector)(与ArrayList相似,区别是Vector是重量级的组件,使用使消耗的资源比较多。) 结论:在考虑并发的情况下用Vector(保证线程的安全)。 在不考虑并发的情况下用ArrayList(不能保证线程的安全)。 面试经验(知识点): java.util.stack(stack即为堆栈)的父类为Vector。可是stack的父类是最不应该为Vector的。因为Vector的底层是数组,且Vector有get方法(意味着它可能访问到并不属于最后一个位置元素的其他元素,很不安全)。 对于堆栈和队列只能用push类和get类。 Stack类以后不要轻易使用。 !!!实现堆栈一定要用LinkedList。 (在JAVA1.5中,collection有queue来实现队列。) Set-HashSet实现类: 遍历一个Set的方法只有一个:迭代器(interator)。 HashSet中元素是无序的(这个无序指的是数据的添加顺序和后来的排列顺序不同),而且元素不可重复。 在Object中除了有final(),toString(),equals(),还有hashCode()。 HashSet底层用的也是数组。 当向数组中利用add(Object o)添加对象的时候,系统先找对象的hashCode: int hc=o.hashCode(); 返回的hashCode为整数值。 Int I=hc%n;(n为数组的长度),取得余数后,利用余数向数组中相应的位置添加数据,以n为6为例,如果I=0则放在数组a[0]位置,如果I=1,则放在数组a[1]位置。如果equals()返回的值为true,则说明数据重复。如果equals()返回的值为false,则再找其他的位置进行比较。这样的机制就导致两个相同的对象有可能重复地添加到数组中,因为他们的hashCode不同。 如果我们能够使两个相同的对象具有相同hashcode,才能在equals()返回为真。 在实例中,定义student对象时覆盖它的hashcode。 因为String类是自动覆盖的,所以当比较String类的对象的时候,就不会出现有两个相同的string对象的情况。 现在,在大部分的JDK中,都已经要求覆盖了hashCode。 结论:如将自定义类用hashSet来添加对象,一定要覆盖hashcode()和equals(),覆盖的原则是保证当两个对象hashcode返回相同的整数,而且equals()返回值为True。 如果偷懒,没有设定equals(),就会造成返回hashCode虽然结果相同,但在程序执行的过程中会多次地调用equals(),从而影响程序执行的效率。 我们要保证相同对象的返回的hashCode一定相同,也要保证不相同的对象的hashCode尽可能不同(因为数组的边界性,hashCode还是可能相同的)。例子: public int hashCode(){ return name.hashcode()+age; } 这个例子保证了相同姓名和年龄的记录返回的hashCode是相同的。 使用hashSet的优点: hashSet的底层是数组,其查询效率非常高。而且在增加和删除的时候由于运用的hashCode的比较开确定添加元素的位置,所以不存在元素的偏移,所以效率也非常高。因为hashSet查询和删除和增加元素的效率都非常高。 但是hashSet增删的高效率是通过花费大量的空间换来的:因为空间越大,取余数相同的情况就越小。HashSet这种算法会建立许多无用的空间。 达内java学习笔记 17 使用hashSet接口时要注意,如果发生冲突,就会出现遍历整个数组的情况,这样就使得效率非常的低。 练习:new一个hashset,插入employee对象,不允许重复,并且遍历出来。 添加知识点: 集合对象存放的是一系列对象的引用。 例: Student S Al.add(s); s.setName(“lucy”); Student s2=(Student)(al.get(o1)); 可知s2也是s。 12.05 SortedSet可自动为元素排序。 SortedSet的实现类是TreeSet:它的作用是字为添加到TreeSet中的元素排序。 练习:自定义类用TreeSet排序。 与HashSet不同,TreeSet并不需要实现HashCode()和equals()。 只要实现compareable和compareTo()接可以实现过滤功能。 (注:HashSet不调用CompareTo())。 如果要查询集合中的数据,使用Set必须全部遍历,所以查询的效率低。使用Map,可通过查找key得到value,查询效率高。 集合中常用的是:ArrayList,HashSet,HashMap。其中ArrayList和HashMap使用最为广泛。 使用HashMap,put()表示放置元素,get()表示取元素。 遍历Map,使用keySet()可以返回set值,用keySet()得到key值,使用迭代器遍历,然后使用put()得到value值。 上面这个算法的关键语句: Set s=m.keySet(); Interator it=new interator(); Object key=it.next(); Object value=m.get(key); 注意:HashMap与HashCode有关,用Sort对象排序。 如果在HashMap中有key值重复,那么后面一条记录的value覆盖前面一条记录。 Key值既然可以作为对象,那么也可以用一个自定义的类。比如: m.put(new sutdent(“Liucy”,30),”boss”) 如果没有语句来判定Student类对象是否相同,则会全部打印出来。 当我们用自定义的类对象作为key时,我们必须在程序中覆盖HashCode()和equals()。 注:HashMap底层也是用数组,HashSet底层实际上也是HashMap,HashSet类中有HashMap属性(我们如何在API中查属性)。HashSet实际上为(key.null)类型的HashMap。有key值而没有value值。 达内java学习笔记 18 正因为以上的原因,TreeSet和TreeMap的实现也有些类似的关系。 注意:TreeSet和TreeMap非常的消耗时间,因此很少使用。 我们应该熟悉各种实现类的选择——非常体现你的功底。 HashSet VS TreeSet:HashSet非常的消耗空间,TreeSet因为有排序功能,因此资源消耗非常的高,我们应该尽量少使用,而且最好不要重复使用。 基于以上原因,我们尽可能的运用HashSet而不用TreeSet,除非必须排序。 同理:HashMap VS TreeMap:一般使用HashMap,排序的时候使用TreeMap。 HashMap VS Hashtable(注意在这里table的第一个字母小写)之间的区别有些类似于ArrayList和Vector,Hashtable是重量级的组件,在考虑并发的情况,对安全性要求比较高的时候使用。 Map的运用非常的多。 使用HashMap(),如果使用自定义类,一定要覆盖HashCode()和equals()。 重点掌握集合的四种操作:增加、删除、遍历、排序。 Module8—12利用两天的时间完成。 Module8:图形界面 Module9:事件模型(在本部分最重要) Module10:AWT Module11:Swing Module12:Applet(这个技术基本已经被淘汰) 软件应用的三个发展阶段: 单机应用 网络应用(C/S结构) BS结构:B表示浏览器,S表示server端。即利用浏览器作为客户端,因此对于图形界面的要求已经不高,现在的发展趋势是不使用安装,即不用任何的本地应用,图形很快就会被服务器构件开发所取代。 经验之谈:Swing的开发工作会非常的累,而且这项技术正在走向没落。避免从事有这种特征的工作。 AWT也即将被取代。 Module8—Module11所使用的技术都将被JSF技术所取代。 JSF是服务器端的Swing:目前技术已经成熟,但是开发环境(工具)还不成熟。 Module12的Applet技术也将被WebStart所取代。 Module9为重点,所谓事件模型是指观察者设计模式的JAVA应用。事件模型是重点。 Module8:图形界面(java.awt.*) Awt:抽象窗口工具箱,它由三部分组成: ①组件:界面元素; ②容器:装载组件的容器(例如窗体); ③布局管理器:负责决定容器中组件的摆放位置。 图形界面的应用分四步: ① 选择一个容器: ⑴window:带标题的容器(如Frame); ⑵Panel:面板 通过add()想容器中添加组件。 Java的图形界面依然是跨平台的。但是在调用了一个窗体之后只生成一个窗体,没有事件的处理,关闭 达内java学习笔记 19 按钮并不工作。此时只能使用CTRL+C终止程序。 ②设置一个布局管理器:用setLayout(); ③向容器中添加组件; ③ 添加组件的事务处理。P198 P204:Panel也是一种容器:但是不可见的。在设置容易的时候不要忘记设置它们的可见性。 Panel pan=new Panel; Fp.setLayout(null);表示不要布局管理器。 五种布局管理器: P206:Flow Layout(流式布局):按照组件添加到容器中的顺序,顺序排放组件位置。默认为水平排列,如果越界那么会向下排列。排列的位置随着容器大小的改变而改变。 Panel默认的布局管理器为Flow Layout。 Border Layout:会将容器非常五个区域:东西南北中。 语句: Button b1=new Botton(“north”);//botton上的文字 f.add(b1,”North”);//表示b1这个botton放在north位置 注:一个区域只能放置一个组件,如果想在一个区域放置多个组件就需要使用Panel来装载。 Frame和Dialog的默认布局管理器是Border Layout。 Grid Layout:将容器生成等长等大的条列格,每个块中放置一个组件。 f.setLayout GridLayout(5,2,10,10)//表示条列格为5行2类,后面为格间距。 CardLayout:一个容器可以放置多个组件,但每次只有一个组件可见(组件重叠)。 使用first(),last(),next()可以决定哪个组件可见。可以用于将一系列的面板有顺序地呈现给用户。 重点:GridBag Layout:在Grid中可指定一个组件占据多行多列,GridBag的设置非常的烦琐。 Module9:AWT:事件模型 事件模型指的是对象之间进行通信的设计模式。 对象1给对象2发送一个信息相当于对象1引用对象2的方法。 模型即是一种设计模式(约定俗成) 对象对为三种: ①事件源:发出事件者; ②事件对象:发出的事件本身; ④ 事件监听器:提供处理事件指定的方法。 Java AWT事件模型也称为授权事件模型,指事件可以和监听器之间事先建立一种关系:约定那些事件如何处理,由谁去进行处理。这种约定称为授权。 一个事件源可以授权多个监听者(授权也称为监听者的注册); 多个事件源也可以注册多个事件监听器。 监听者对于事件源的发出的事件作出响应。 在java.util中有EventListener接口:所有事件监听者都要实现这个接口。 java.util中有EventObject类:所有的事件都为其子类。 事件范例在\\CoreJava\\Girl.java文件中。(文件已加注释) 达内java学习笔记 20