java集合是在编程中经常用到的工具类,也是工具类,清楚他们在不同环境下应用时的性能问题对我们的编程会有很大帮助。
集合类主要由两个接口派生:collection和Map。
Collection接口是list,set和Queue的父接口,定义了操作List,queue和Set集合的方法,主要包括添加,清除,判断为空,遍历等方法。
map用于操作具有映射关系的数据,通过key和value的形式进行存储,它们是单向一一对应的关系。单纯看key或者value值都是set集合,特点是无序。
问题1:数组与集合的关系?
最根本的区别是保存的数据类型不一样,数组可以保存基本类型和对象的数据,集合只能用于保存对象。
问题2:关于集合的运算主要包括哪些?都如何实现?
在数据结构这门学科中我们经常讨论的是查询,遍历和排序,同样在集合当中经常考虑的也是这几个问题。
1. 遍历:
(1)关于遍历,经常用到的是iterator和foreache循环。对比两种遍历方式,iterator在链式结构中(如LinkedList,LinkedHashMap)遍历速度快,foreach则在线性数据中(ArrayList,Hashmap等)速度更快;同时,iterator采用快速失败机制,在多线程操作过程中,检测到集合被修改,立即引发concurrentmodificationException错误。
(2)在List遍历方式中,iterator提供了ListIterator子接口。Iterator只能顺序遍历自己的元素,而listrator可以对遍历的元素进行增删改查,逆向遍历等。
(3)java8还提供了使用lamda表达式进行遍历的方式,具体实现如下:
iterator.forEachRemaining(obj->System.out.println(obj)).
2.查询:
查询在一定条件下必须经过比较,但是一般对象的比较都要重写equals方法和hashcode方法。这是为什么呢?因为默认的object对象的equals方法比较的是对象地址,创建的两个同名同姓的人不一定相等,因此我们要重写equals方法。对象生成时会生成int类型的散列值(hashcode),hashmap对象实际上是根据key值得hashcode值查找value,因此必须要重写hashcode方法。
重写方式:
class R{
int count;
public R(int count){
this.count=count;
}
public String toString(){
return "R[count:"+count+"]";
}
public boolean equals(objcet obj){
if(this==obj)
return true;
if(obj!=null && obj.getClass()==R.class){
R r=(R)obj;
return this.count==r.count;
}
return false;
}
public int hashCode(){
return this.count;
}
}
集合提供的TreeSet和TreeMap都是在排序状态。分为自然排序和定制排序(按照某个字段进行排序),自然排序compareTo(Object obj)比较,将集合元素进行升序排列。
public int compareTo(Object obj){
R r=(R)obj;
return count>r.count?1:count <r.count?-1:0;
}
定制排序如实现降序排序,可以通过Comparator接口的帮助,定义compare(o1,o2)方法比较两者的大小,相等返回0,大于返回1,小于返回-1进行排序。
TreeSet ts=new TreeSet((o1,o2)->{
M m1=(M)o1;
M m2=(M)o2;
return m1.age>m2.age?-1:m1.age<m2.age?1:0;
});