在接触了java的这段时间内发现java帮我们coder做了很多很多事情,让编程变得更简单了,但同时也让coder变得更白痴了.就像很多公司的java coder,在app里面,好像不是数组就是arraylist,固之然arraylist的确很好用,可以随机访问、自动增加容量的数组.这东西在我学习C的时候是从来没出现过的,或者可以说不敢想象能做的出来,而java就帮我们的coder实现了,但也像我之前说的,让我们变得更笨了,好像任何时候用arraylist就可以了,那事实是真的这样吗?
例如存储不可重复的元素,例如操作多删除和多插入的数据,这时候arraylist肯定不是最好的选择.作为程序员,脑袋肯定不能是死的,也不能按部就班,不能有"我知道怎么用就好的想法".所以今天我就复习一下java的数据结构
数据元素之间的相互关系:
1.集合结构
2.线性结构
3.树状结构
4.图形结构
在存储结构中又可以分为(即在内存或者外置存储器中存储的方式):
1.顺序存储结构
2.链式存储结构
那么在java中主要的表现形式分为2种:
1:collection
2.MAP
MAP分为:
Hashtable 和hashmap
先从简单的说起,java中的表现形式:
1.collection
list
arraylist
vector
linkedlist
set
hashset
treeset
他们的区别可以这么分
1.list是一个有序的,有索引,可以重复的,可以说怎么存,就怎么取出来
2.set是无序的,而且不可以重复
LIST的区别
1.arraylist的底层是一个数组,因为数组的特性,所以修改成员就很方便了,少量的增删改查也是比linekedlist要好的.这也是日常开发中经常使用到的list.但是正是因为他是线程不安全的,所以速度快
2.linekedlist的底层是一个链表,而且是一个双向的链表.那么在删除和增加上面就有天生的优势,只需要修改头结点和尾节点就好了,但是只要涉及到类似索引的问题就会慢起来
3.vector是线程安全的数组,不过早就被谷歌抛弃了
SET的区别
1.hashset的底层排序用的是hash算法,需要重写hashcode和equad.
2.treeset的底层用的是二叉树的排序算法,但是treeset有两种排序方式:
a:自然排序(comparable):
treeset类的add()方法中会把存入的对象提升为comparable类型
调用对象的compareto()方法和集合中的对象比较
根据comparato()方法返回的结果进行存储
b:比较器顺序(comparator):
创建treeset的时候可以指定一个比较器(comparator)
如果传入了comparator的子类对象,那么treeset就会按照比较器中的顺序排序
add()方法内部会自动调用comparator接口中的compara方法排序
那么我们讲讲list和set的遍历区别:
- 1.List
- a.普通for循环, 使用get()逐个获取
- b.调用iterator()方法得到Iterator, 使用hasNext()和next()方法
- c.增强for循环, 只要可以使用Iterator的类都可以用
- d.Vector集合可以使用Enumeration的hasMoreElements()和nextElement()方法
- 2.Set
- a.调用iterator()方法得到Iterator, 使用hasNext()和next()方法
- b.增强for循环, 只要可以使用Iterator的类都可以用
- 3.普通for循环,迭代器,增强for循环是否可以在遍历的过程中删除
2.MAP
hashtable
hashmap
map的表现形式就是键值对,唯一的键,但是值不是唯一,当键是自定义对象的时候,必须要重写hashcode和equal方法才可以形成唯一性
MAP迭代的方式有两种:
1:keyset
HashMap<String, Integer> hm = new HashMap<>();
hm.put("张三", 23);
hm.put("李四", 24);
hm.put("王五", 25);
hm.put("赵六", 26);
/*Set<String> keySet = hm.keySet(); //获取集合中所有的键
Iterator<String> it = keySet.iterator(); //获取迭代器
while(it.hasNext()) { //判断单列集合中是否有元素
String key = it.next(); //获取集合中的每一个元素,其实就是双列集合中的键
Integer value = hm.get(key); //根据键获取值
System.out.println(key + "=" + value); //打印键值对
}*/
for(String key : hm.keySet()) { //增强for循环迭代双列集合第一种方式
System.out.println(key + "=" + hm.get(key));
}
2:entryset
HashMap<String, Integer> hm = new HashMap<>();
hm.put("张三", 23);
hm.put("李四", 24);
hm.put("王五", 25);
hm.put("赵六", 26);
/*Set<Map.Entry<String, Integer>> entrySet = hm.entrySet(); //获取所有的键值对象的集合
Iterator<Entry<String, Integer>> it = entrySet.iterator();//获取迭代器
while(it.hasNext()) {
Entry<String, Integer> en = it.next(); //获取键值对对象
String key = en.getKey(); //根据键值对对象获取键
Integer value = en.getValue(); //根据键值对对象获取值
System.out.println(key + "=" + value);
}*/
for(Entry<String,Integer> en : hm.entrySet()) {
System.out.println(en.getKey() + "=" + en.getValue());
}
java给collections提供了一些常用的算法:
public static <T> void sort(List<T> list) //排序
public static <T> int binarySearch(List<?> list,T key) //二分查找法
public static <T> T max(Collection<?> coll)//最大值
public static void reverse(List<?> list) //翻转
public static void shuffle(List<?> list) //随机排序