黑马程序员——集合框架
2015-06-01 15:56
417 查看
------- android培训、java培训、期待与您交流! ----------
集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。
java集合框架:
1. 什么是框架:类库的集合
2.集合框架:用来表示和操作的统一的架构,包含了实现集合的接口与类
3.集合:存放数据的容器
集合框架包含了两部分:一部分是接口,一部分是类
4.为什么会出现接口:因为集合框架中的很多类 功能是相似的(所以用接口来规范类)
java集合类是一种工具类,用于存储不定长度的数据。Java集合可以大致分为Set,List和Map三种体系,其中Set代表无序、不可重复的集合;List代表有序、重复的集合;而Map代表具有映射关系的集合。从Java5之后又增加了Queue体系集合,代表一种队列集合实现。
集合类的出现是为了在编程时保存数量不确定的数据,以及具有映射关系的数据(也就是关系数组),所以也称集合类为容器类。集合类都位于Java.util包下,为解决线程并发问题Java5之后还在Java.util.concurrent包下提供了支持多线程的集合类。其与数组不一样,数组元素可以保存基本数据类型的值,也可以是对象;而集合类只允许保存对象的引用变量。
Java中的集合类主要有两个接口派生:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类。
一:常用集合类之间的层次、继承关系
Collection
|--List:元素是有序的,元素可以重复。因为飞机和体系有索引。
|--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度快,但是增删稍慢。
|--LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。
|--Vector:底层是数组结构,线程同步,被ArrayList替代了,因为效率低。
|--Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。
|--HashSet:底层数据结构是哈希表。HashSet通过hashCode和equals判断元素是否重复。如果元素的hashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals。对于判断元素是否存在,以及删除等操作依赖的方法是元素的hashCode和equals方法。
|--LinkedSet:通过hashcode确定元素的存储位置,同时通过链表确定元素的顺序。
|--TreeSet:可以对Set集合中的元素进行排序,底层数据结构是二叉树。它保证元素唯一性的依据是compareTo方法的return。TreeSet默认顺序采用的是红黑树。TreeSet允许自定义排序方式:当元素自身不具备比较性时,或者具备的比较性不是所需的,这是就需要让集合自身具备比较性,在集合初始化时就让其具有比较性方式。
|--EnumSet:专门为枚举类设计的集合类,其中所有的元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显式或隐式的指定。EnumSet的集合元素也是有序的,EnumSet以枚举值在Enum内部的定义顺序来决定集合元素的顺序。
|--Map:用于保存具有映射关系的数据。
|--HashMap:底层数据结构是哈希表。HashMap通过hashCode和equals判断元素是否重复。如果元素的hashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals。
|--TreeMap:可以对Map集合中的元素进行排序,底层数据结构是二叉树。它保证元素唯一性的依据是compareTo方法的return。TreeSet默认顺序采用的是红黑树。TreeSet允许自定义排序方式:当元素自身不具备比较性时,或者具备的比较性不是所需的,这是就需要让集合自身具备比较性,在集合初始化时就让其具有比较性方式。
|--EnumMap:与枚举类一起使用的Map实现,EnumMap中的所有KEY都必须是单个枚举类的枚举值。创建EnumMap的时候必须显式或隐式的指定它对应的枚举类。
|--Queue:用于模拟队列这种数据结构,不允许随机访问。
|--PriorityQueue:数据的存储不按照加入队列的顺序,而是按照队列元素的大小重新排序。因此,当取出队列元素时,取出的并不是最先加入队列元素而是最小的元素。
|--ArrayQueue:基于数组实现的是双端队列。
List:
特有方法,凡是可以操作角标的方法都是该体系特有的方法
增
add(intindex,Eelement);
addAll(index,Collection);
删
remove(index);
改
set(index,element);
查
get(index);
subList(form,to);
listIterator();
List集合特有的迭代器,ListIterator是Iterator的子接口
在迭代时,不可以通过集合对象的方法操作集合中的元素
因为会发生ConcurrentModificationException并发操作异常
所以,在迭代时,只能用迭代器的方法操作元素,可以Iterator方法是有限的
只能对元素进行判断,取出和删除的操作
如果想要其他的操作如添加,修改等,就需要使用其子接口ListIterator
该接口只能通过List集合listIterator方法获取
Map集合:该集合存储键值对一对一对往里存而且要保证键的唯一性
1.添加
put(Kkey,Vvalue)
putAll(Map<?extendsK,?extendsV>m)
2.删除
clear()
remove(Objectkey)
3.判断
containsKey(Objectvalue)
containsValue(Objectvalue)
isEmpty()
4.获取
size()
values()
get(Objectkey)
keySet()
entrySet()
Set:无序,不可以重复元素
--HashSet:数据结构是哈希表,线程是非同步的
保证元素唯一性的原理,判断元素的hashCode值是否相同
如果相同,还会继续判断元素的equals方法,是否为true
--TreeSet:可以对Set集合中的元素进行排序
底层数据结构是二叉树
1,保证元素唯一性的依据compareTo方法return0。
2,当元素不具备比较性时,或者具备的比较性不是所需要的
这时就需要让集合自身具备比较性
在集合初始化时,就有了比较方式
需求;
往TreeSet集合中存储自定义对象学生
想按照学生的年龄进行排序
记住:排序时,当主要条件相同时,一定判断次要条件
Map
Hashtable:底层是哈希表数据结构,不可以存入null键null值,该集合是线程同步的
HashMap:底层是哈希表数据结构允许使用null值和null键该集合是不同步的
TreeMap:底层是二叉树数据结构,线程不同步,可以用于给Map集合中的键进行排序
和Set很像
Set底层就是使用了Map集合
map集合的两种取出方式
1.Ser<k>keySet:将map中所有的键存入到Set集合,因为Set集合具备迭代器,
所以可以用迭代方式取出所有的键,再根据ger方法,获取每一个键对应的值
Map集合的取出原理:将map集合转换成set集合再通过迭代器取出
2.Ser<Map.Entry<k,v>>entrySet:将map集合中的映射关系存入到了set集合中,
而这个关系的数据类型就是:Map.Entry
对于HashSet和TreeSet它们的排序是如何进行的呢?
覆盖compareTo的方法
TreeSet 是否用的二叉树算法插入数据?
hashcode()与 equals()
hashcode 重写一般只有用于集合的时候才有用
equals() 则是判断调用方法
HashSe 与 TreeSet 类示例
集合框架中的工具类
Collections
对集合进行查找
取出集合中的最大值,最小值
对List集合进行排序
……
Arrays
将数组转成List集合
对数组进行排序
1、两个对象值相同(x.equals(y)==true),但却可有不同的hashcode,这句话对不对?
对。
如果对象要保存在HashSet或HashMap中,它们的equals相等,那么,它们的hashcode值就必须相等。
如果不是要保存在HashSet或HashMap,则与hashcode没有什么关系了,这时候hashcode不等是可以的,例如arrayList存储的对象就不用实现hashcode,当然,我们没有理由不实现,通常都会去实现的。
2、TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常?
集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。
java集合框架:
1. 什么是框架:类库的集合
2.集合框架:用来表示和操作的统一的架构,包含了实现集合的接口与类
3.集合:存放数据的容器
集合框架包含了两部分:一部分是接口,一部分是类
4.为什么会出现接口:因为集合框架中的很多类 功能是相似的(所以用接口来规范类)
java集合类是一种工具类,用于存储不定长度的数据。Java集合可以大致分为Set,List和Map三种体系,其中Set代表无序、不可重复的集合;List代表有序、重复的集合;而Map代表具有映射关系的集合。从Java5之后又增加了Queue体系集合,代表一种队列集合实现。
集合类的出现是为了在编程时保存数量不确定的数据,以及具有映射关系的数据(也就是关系数组),所以也称集合类为容器类。集合类都位于Java.util包下,为解决线程并发问题Java5之后还在Java.util.concurrent包下提供了支持多线程的集合类。其与数组不一样,数组元素可以保存基本数据类型的值,也可以是对象;而集合类只允许保存对象的引用变量。
Java中的集合类主要有两个接口派生:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类。
一:常用集合类之间的层次、继承关系
Collection
|--List:元素是有序的,元素可以重复。因为飞机和体系有索引。
|--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度快,但是增删稍慢。
|--LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。
|--Vector:底层是数组结构,线程同步,被ArrayList替代了,因为效率低。
|--Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。
|--HashSet:底层数据结构是哈希表。HashSet通过hashCode和equals判断元素是否重复。如果元素的hashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals。对于判断元素是否存在,以及删除等操作依赖的方法是元素的hashCode和equals方法。
|--LinkedSet:通过hashcode确定元素的存储位置,同时通过链表确定元素的顺序。
|--TreeSet:可以对Set集合中的元素进行排序,底层数据结构是二叉树。它保证元素唯一性的依据是compareTo方法的return。TreeSet默认顺序采用的是红黑树。TreeSet允许自定义排序方式:当元素自身不具备比较性时,或者具备的比较性不是所需的,这是就需要让集合自身具备比较性,在集合初始化时就让其具有比较性方式。
|--EnumSet:专门为枚举类设计的集合类,其中所有的元素都必须是指定枚举类型的枚举值,该枚举类型在创建EnumSet时显式或隐式的指定。EnumSet的集合元素也是有序的,EnumSet以枚举值在Enum内部的定义顺序来决定集合元素的顺序。
|--Map:用于保存具有映射关系的数据。
|--HashMap:底层数据结构是哈希表。HashMap通过hashCode和equals判断元素是否重复。如果元素的hashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals。
|--TreeMap:可以对Map集合中的元素进行排序,底层数据结构是二叉树。它保证元素唯一性的依据是compareTo方法的return。TreeSet默认顺序采用的是红黑树。TreeSet允许自定义排序方式:当元素自身不具备比较性时,或者具备的比较性不是所需的,这是就需要让集合自身具备比较性,在集合初始化时就让其具有比较性方式。
|--EnumMap:与枚举类一起使用的Map实现,EnumMap中的所有KEY都必须是单个枚举类的枚举值。创建EnumMap的时候必须显式或隐式的指定它对应的枚举类。
|--Queue:用于模拟队列这种数据结构,不允许随机访问。
|--PriorityQueue:数据的存储不按照加入队列的顺序,而是按照队列元素的大小重新排序。因此,当取出队列元素时,取出的并不是最先加入队列元素而是最小的元素。
|--ArrayQueue:基于数组实现的是双端队列。
List:
特有方法,凡是可以操作角标的方法都是该体系特有的方法
增
add(intindex,Eelement);
addAll(index,Collection);
删
remove(index);
改
set(index,element);
查
get(index);
subList(form,to);
listIterator();
List集合特有的迭代器,ListIterator是Iterator的子接口
在迭代时,不可以通过集合对象的方法操作集合中的元素
因为会发生ConcurrentModificationException并发操作异常
所以,在迭代时,只能用迭代器的方法操作元素,可以Iterator方法是有限的
只能对元素进行判断,取出和删除的操作
如果想要其他的操作如添加,修改等,就需要使用其子接口ListIterator
该接口只能通过List集合listIterator方法获取
import java.util.*; /* 1.add方法的参数类型是Object,以便于接受任意类型对象 2.方法中存储的都是对象的引用或者地址 什么是迭代器呢? 其实就是集合的取出元素的方式 */ class CollectionDemo { publicstatic void main(String[] args) { //method_2(); //base_method(); get_method(); } publicstatic void sop(Object obj) { System.out.println(obj); } publicstatic void base_method() { //创建一个集合容器,使用Collection接口的子类:ArrayList ArrayListal = new ArrayList(); //1,添加元素 al.add("java01");//add()参数类型是Object类型的,因为可以是任意对象 al.add("java02"); al.add("java03"); al.add(4); sop("原集合:" + al); //2.获取个数,集合长度size(); sop("size="+ al.size()); //3.删除元素 al.remove("java02"); sop("改变后的集合:" + al); al.clear();//清空集合 sop(al); //4.判断集合是否为空 sop("判断元素是否存在" + al.contains("java01")); sop("判断集合是否为空" + al.isEmpty()); } publicstatic void method_2() { ArrayListal1 = new ArrayList(); al1.add("java01");//add()参数类型是Object类型的,因为可以是任意对象 al1.add("java02"); al1.add("ja 4000 va03"); ArrayListal2 = new ArrayList(); al2.add("java05");//add()参数类型是Object类型的,因为可以是任意对象 al2.add("java06"); al2.add("java04"); al2.retainAll(al1);//取交集,al1中只会保留和al2中相同的元素 sop("al1:"+ al1); sop("al2:"+ al2); } publicstatic void get_method() { ArrayListal = new ArrayList(); al.add("java01"); al.add("java02"); al.add("java03"); al.add(4); /* * Iterator it = al.iterator();//返回的是Iterator接口类型的对象,Iterator是一个集合的内部类 * while (it.hasNext()) { sop(it.next()); } */ for(Iterator it = al.iterator(); it.hasNext();)// 这样写不用在迭代结束后还保留it对象,因为it是for循环的一个内部变量,便于内存管理 { sop(it.next()); } } }
import java.util.*; class ListDemo { publicstatic void main(String[] args) { //method(); //演示列表迭代器 ArrayListal = new ArrayList(); //添加元素 al.add("java01"); al.add("java02"); al.add("java03"); al.add(4); sop("原集合是:" + al); ListIteratorli = al.listIterator(); while(li.hasNext()) { Objectobj = li.next(); if(obj.equals("java02")) li.set("java006"); if(obj.equals("java03")) li.add("new"); sop("obj="+ obj); } sop(li.hasNext()); sop(li.hasPrevious()); sop("改变后的集合:" + al); //在迭代过程中,准备添加或者删除元素 /* * Iterator it = al.iterator(); while(it.hasNext()) { Object obj = * it.next(); if(obj.equals("java02")) * //al.add("java008");//这步操作可能会引起并发访问异常,因为al有两种操作方式,容易产生安全隐患 * it.remove(); * sop("obj="+obj);//迭代过程中即使删除的元素也会被obj引用,所以也能打印出来,而且Iterator只有三个方法,有局限性 * } */ } publicstatic void method() { ArrayListal = new ArrayList(); //添加元素 al.add("java01"); al.add("java02"); al.add("java03"); al.add(4); sop("原集合是:" + al); //在指定位置添加元素 al.add(1,"java09"); //删除指定位置的元素 //all.remove(2); //修改元素 al.set(2,"java007"); //通过角标获取元素 //sop("get(1):"+al.get(1)); //sop(al); //获取所有元素 for(int x = 0; x < al.size(); x++) { sop("al("+ x + ")=" + al.get(x)); } Iteratorit = al.iterator(); while(it.hasNext()) { sop(it.next()); } //通过indexOf获取对象的位置 sop("index="+ al.indexOf("java09")); Listsub = al.subList(1, 4); sop("sub="+ sub); } publicstatic void sop(Object obj) { System.out.println(obj); } }
import java.util.*; /* LinkedList:特有方法 addFist(); addLast(); getFirst(); getLast(); removeFirst(); removeFirst(); JDK1.6以后出现了替代方法: offerFirst(); offerFirst(); peekFirst(); peekLast();如果没有元素,则返回null pollFirst(); pollLast();如果没有元素,则返回null */ class LinkedDemo { publicstatic void main(String[] args) { LinkedListlink = new LinkedList(); link.addFirst("java01"); link.addFirst("java02"); link.addFirst("java03"); link.addFirst("java04"); sop(link); sop(link.getFirst()); sop(link.getLast()); sop(link.size()); sop(link.removeFirst()); sop(link.size()); while(!link.isEmpty()) { sop(link.removeFirst()); } } publicstatic void sop(Object obj) { System.out.println(obj); } }
Map集合:该集合存储键值对一对一对往里存而且要保证键的唯一性
1.添加
put(Kkey,Vvalue)
putAll(Map<?extendsK,?extendsV>m)
2.删除
clear()
remove(Objectkey)
3.判断
containsKey(Objectvalue)
containsValue(Objectvalue)
isEmpty()
4.获取
size()
values()
get(Objectkey)
keySet()
entrySet()
Set:无序,不可以重复元素
--HashSet:数据结构是哈希表,线程是非同步的
保证元素唯一性的原理,判断元素的hashCode值是否相同
如果相同,还会继续判断元素的equals方法,是否为true
--TreeSet:可以对Set集合中的元素进行排序
底层数据结构是二叉树
1,保证元素唯一性的依据compareTo方法return0。
2,当元素不具备比较性时,或者具备的比较性不是所需要的
这时就需要让集合自身具备比较性
在集合初始化时,就有了比较方式
需求;
往TreeSet集合中存储自定义对象学生
想按照学生的年龄进行排序
记住:排序时,当主要条件相同时,一定判断次要条件
import java.util.*; class TreeSetDemo { publicstatic void main(String[] args) { TreeSetts = new TreeSet(); ts.add(newStudent("lisi02", 22)); ts.add(newStudent("lisi007", 20)); ts.add(newStudent("lisi09", 19)); ts.add(newStudent("lisi08", 19)); Iteratorit = ts.iterator(); while(it.hasNext()) { Studentstu = (Student) it.next(); System.out.println(stu.getName()+ "::" + stu.getAge()); } } } class Student implements Comparable// 该接口强制让学生具备比较性 { privateString name; privateint age; Student(Stringname, int age) { this.name= name; this.age= age; } publicint compareTo(Object obj) { if(!(obj instanceof Student)) thrownew RuntimeException("不是学生对象"); Students = (Student) obj; System.out.println(this.name+ "::compare to::" + s.name); if(this.age > s.age) return1; if(this.age == s.age) { returnthis.name.compareTo(s.name); } ; return-1; } publicString getName() { returnname; } publicint getAge() { returnage; } }
Map
Hashtable:底层是哈希表数据结构,不可以存入null键null值,该集合是线程同步的
HashMap:底层是哈希表数据结构允许使用null值和null键该集合是不同步的
TreeMap:底层是二叉树数据结构,线程不同步,可以用于给Map集合中的键进行排序
和Set很像
Set底层就是使用了Map集合
map集合的两种取出方式
1.Ser<k>keySet:将map中所有的键存入到Set集合,因为Set集合具备迭代器,
所以可以用迭代方式取出所有的键,再根据ger方法,获取每一个键对应的值
Map集合的取出原理:将map集合转换成set集合再通过迭代器取出
import java.util.*; public class MapDemo2 { publicstatic void main(String[] args) { Map<String,String> map = new HashMap<String, String>(); map.put("02","zhangshan02"); map.put("03","zhangshan03"); map.put("01","zhangshan01"); map.put("04","zhangshan04"); //先获取map集合的所有键的Set集合,keySet(); Set<String>keySet = map.keySet(); //有了Set集合,就可以获取其迭代器 Iterator<String>it = keySet.iterator(); while(it.hasNext()) { Stringkey = it.next(); //有了键可以通过map集合的get方法获取其对应的值 Stringvalue = map.get(key); System.out.println("key--"+ key + ",value" + value); } } }
2.Ser<Map.Entry<k,v>>entrySet:将map集合中的映射关系存入到了set集合中,
而这个关系的数据类型就是:Map.Entry
对于HashSet和TreeSet它们的排序是如何进行的呢?
覆盖compareTo的方法
TreeSet 是否用的二叉树算法插入数据?
hashcode()与 equals()
hashcode 重写一般只有用于集合的时候才有用
equals() 则是判断调用方法
HashSe 与 TreeSet 类示例
import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; import java.util.TreeSet; public class HashSetTest { publicstatic void main(String[] args) { Perp1 = new Per(12); p1.idCard= "1"; Perp2 = new Per(33); p2.idCard= "1"; HashSet<Per>hs = new HashSet<Per>(); hs.add(p1); hs.add(p2); p2.idCard= "3"; System.out.println(hs.size()); Iterator<Per>it = hs.iterator(); while(it.hasNext()) { System.out.println(it.next()); } Perp3 = new Per(22); Perp4 = new Per(15); Perp5 = new Per(17); //实现 Comparator接口 设置排序方式 TreeSet<Per>ts = new TreeSet<Per>(new Comparator<Per>() { @Override publicint compare(Per o1, Per o2) { //TODO Auto-generated method stub returno1.age - o2.age; } }); ts.add(p1); ts.add(p2); ts.add(p3); ts.add(p4); ts.add(p5); System.out.println(ts.size()); Iterator<Per>it2 = ts.iterator(); while(it2.hasNext()) { System.out.println(it2.next()); } } } class Per { StringidCard; Stringname; intage; publicPer() { } publicPer(int age) { this.age= age; } @Override publicint hashCode() { finalint prime = 31; intresult = 1; result= prime * result + ((idCard == null) ? 0 : idCard.hashCode()); returnresult; } @Override publicboolean equals(Object obj) { if(this == obj) returntrue; if(obj == null) returnfalse; if(getClass() != obj.getClass()) returnfalse; Perother = (Per) obj; if(idCard == null) { if(other.idCard != null) returnfalse; }else if (!idCard.equals(other.idCard)) returnfalse; returntrue; } @Override publicString toString() { return"Per [idCard=" + idCard + ", name=" + name + ",age=" + age + "]"; } }
集合框架中的工具类
Collections
对集合进行查找
取出集合中的最大值,最小值
对List集合进行排序
……
Arrays
将数组转成List集合
对数组进行排序
public static void main(String[] args){ char[] c = new char[]{'A','c','B','d','E'}; int[] b = new int[]{1,32,22,11,35,21,9,8}; //如果数组类型是基本类型数组 则转成的list集合 没有数据 因为无法对基本类型进行泛型 List ls = Arrays.asList(c); //转换成list 集合 System.out.println(ls.size()); Arrays.sort(c); //排序 System.out.println(Arrays.toString(c)); Arrays.sort(b); int i = Arrays.binarySearch(b,35);; //使用二分法查找 必须先排序 才可以查找该元素 System.out.println(Arrays.toString(b)); System.out.println(i); }
1、两个对象值相同(x.equals(y)==true),但却可有不同的hashcode,这句话对不对?
对。
如果对象要保存在HashSet或HashMap中,它们的equals相等,那么,它们的hashcode值就必须相等。
如果不是要保存在HashSet或HashMap,则与hashcode没有什么关系了,这时候hashcode不等是可以的,例如arrayList存储的对象就不用实现hashcode,当然,我们没有理由不实现,通常都会去实现的。
2、TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常?
public class Parent implementsComparable { privateint age = 0; publicParent(int age){ this.age= age; } publicint compareTo(Object o) { //TODO Auto-generated method stub System.out.println("methodof parent"); Parento1 = (Parent)o; returnage>o1.age?1:age<o1.age?-1:0; } } public class Child extends Parent { publicChild(){ super(3); } publicint compareTo(Object o) { //TODO Auto-generated method stub System.out.println("methodof child"); // Childo1 = (Child)o; return1; } } public class TreeSetTest { /** * @param args */ publicstatic void main(String[] args) { //TODO Auto-generated method stub TreeSetset = new TreeSet(); set.add(newParent(3)); set.add(newChild()); set.add(newParent(4)); System.out.println(set.size()); } }
相关文章推荐
- 黑马程序员——JAVA概述
- 黑马程序员--Java基础学习03
- 黑马程序员——Map集合
- 黑马程序员——Java反射
- 黑马程序员-java之TreeSet,Comparable,Comparator
- 黑马程序员——String类和基本数据类型包装类
- 黑马程序员——单例设计模式
- 黑马程序员-框架技术实现的手段-反射基础
- 面试宝典
- 黑马程序员——Set集合+hashCode+比较器
- 黎活明给程序员的忠告(转)
- 给 程序员 的设计学习指南
- 黑马程序员_Java面向对象_包
- 面试题11:数值的整数次方
- 黑马程序员——多线程
- 程序员编程生涯中会犯的7个错误
- 聊聊做码农的这些年,时光飞逝岁月无痕
- 黑马程序员-Java之HashSet
- 程序员在他们的软件开发生涯中最常犯的7个错误
- 面试题25:二叉树中和为某一值的路径