java之集合
集合的根
- Collection是所有集合的根接口。一些Collection一些子类有些允许有重复元素,有些不允许,一些子类示例中存放的元素是有序的,有些事无序的。
- 集合公有方法:add、addAll、clear、contains、isEmpty、iterator、remove、size、toArray。
集合框架图
List、Queue、Set依然是接口
迭代器
-
我们知道for循环可以遍历数组,这种方法的缺点是事先我们必须知道集合的数据结构,如果我们换一种数据结构的话,for循环可能会不适用,比如set集合,事实上几乎每一种集合都有独自的访问方法,这样代码就不可复用。为什么解决问题,迭代器诞生了。
-
迭代器用一种兼容的机制,可以遍历任何数组结构的集合。
-
方法啊:hasNext、next、remove。
-
使用迭代器器时,集合就不能有remove操作,否则会报错。
-
示例代码
public static void displayElem(Iterator<String> its){ while(its.hasNext()){ System.out.println(its.next()); } } public static void main(String[] args) { List<String>list = new ArrayList<String>(); list.add("test1"); list.add("test2"); list.add("test3"); list.add("test4"); displayElem( list.iterator()); List<String>list1= new LinkedList<String>(); list1.add("test5"); list1.add("test6"); list1.add("test7"); list1.add("test8"); displayElem( list1.iterator()); Set<String> set = new HashSet<>(); set.add("test9"); set.add("test11"); displayElem( set.iterator()); }
-
结果
test1 test2 test3 test4 test5 test6 test7 test8 test9 test11
-
迭代器remove方法使用
-
使用迭代器时,集合remove方法不能使用,否则会报错
public static void main(String[] args) { List<String> all = new ArrayList<String>(); all.add("a"); all.add("b"); all.add("c"); all.add("d"); Iterator<String> iterator=all.iterator();//实例化迭代器 while(iterator.hasNext()){ String str=iterator.next();//读取当前集合数据元素 if("b".equals(str)){ all.remove(str); }else{ System.out.println( str+" "); } } System.out.println("\n删除\"b\"之后的集合当中的数据为:"+all); }
a Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901) at java.util.ArrayList$Itr.next(ArrayList.java:851) at deidaiqi.main(deidaiqi.java:41)
-
可以用迭代器本身的remove方法来进行替换
扫描二维码关注公众号,回复: 5376868 查看本文章List<String> all = new ArrayList<String>(); all.add("a"); all.add("b"); all.add("c"); Iterator<String> iterator = all.iterator();//实例化迭代器 while(iterator.hasNext()){ String str=iterator.next();//读取当前集合数据元素 if("b".equals(str)){ //all.remove(str);//使用集合当中的remove方法对当前迭代器当中的数据元素值进行删除操作(注:此操作将会破坏整个迭代器结构)使得迭代器在接下来将不会起作用 iterator.remove(); }else{ System.out.println( str+" "); } } System.out.println("\n删除\"b\"之后的集合当中的数据为:"+all); }
a c 删除"b"之后的集合当中的数据为:[a, c]
-
列表
-
List是个接口,本身不能被实例化,可以实例化其子类。
-
ArrayList
-
底层数组,特点在于查询速度很快;但是插入,删除元素的时候稍慢.
-
线程不安全
-
示例代码
public static void sop(Object o){ System.out.println(o); }
List list = new ArrayList(); list.add("a");// 向集合中追加元素 sop(list); list.add(1, "b");// 向集合的制定位置中追加元素,其他后移 sop(list); list.addAll(list);// 向集合追加一个collection,只可追加collection,由于java不提供collection的实现,由它的下级接口来实现 list.addAll(4, list);// 与上述含义相同, “4”意为追加元素所放的位置 sop(list); int i = list.size();// 长度 System.out.println(i); list.get(0);// 根据元素下标来取集合中的元素 list.remove(7);// 根据集合中元素下标位置来删除元素 sop(list); // 此方法是用来比较的,与equals比较相似,现在list的元素中有[a, b, a, b, a, b, a],来和"a,b,c"比较会返回false, // 但是注意再用来比较String字符串的时候会进行局部的比较,两组字符串部分相同的情况下会返回true System.out.println(list.contains("a,b,c")); //为了将List转为数组,JDK提供了toArray //实现方式一: String [] array=(String[]) list.toArray(new String[list.size()]); for(String arrays: array) { System.out.print(arrays+" "); } //方式二: String [] arr=new String [list.size()]; list.toArray(arr); for(String arrs: arr) { System.out.print(arrs+" "); } //在集合中判断是否为空 ,不空返回false,空会返回true,常常会与null!=list来共同判定集合是否为空, //null!=list和list.isempty最大的区别是:一个人要喝水,前者判断是否有水杯,后者判断的是水杯是否有水 System.out.println(list.isEmpty());//false System.out.println(null!=list);//true //该方法去比较两个对象时,首先先去判断两个对象是否具有相同的地址,如果是同一个对象的引用,则直接放回true;如果地址不一样, //则证明不是引用同一个对象,接下来就是挨个去比较两个字符串对象的内容是否一致,完全相等返回true,否则false。 //这里会涉及到hashcode相关内容,我会单独开一篇来介绍 list.equals(arr);//false //在集合中查找元素 ,"a"如果有 ,返回所查找元素的下标,如果不存在则返回-1 System.out.println(list.indexOf("a")); //打印集合元素 //方式一: Iterator it=list.iterator(); while(it.hasNext()) { String string=(String) it.next(); System.out.print(string+" "); } //方式二: for (Object o:list) { System.out.print(o+" "); } //方式三: for(int s=0;s<list.size();s++) { System.out.print(list.get(s)+" "); } //将list释放,元素清空,且无返回值 list.clear(); sop(list); }
[a] [a, b] [a, b, a, b, a, b, a, b] 8 [a, b, a, b, a, b, a] false a b a b a b a a b a b a b a false true 0 a b a b a b a a b a b a b a a b a b a b a [] ```
-
-
Vector
-
底层数据结构为数组。
-
Vector比ArrayList出现的早,相当于ArrayList的前身,大多数情况下使用ArrayLsit,因为效率较高。
-
Vector线程安全。
-
与ArrayList区别
-
队
-
LinkedList(双向队列)
-
底层链表:查询速度非常慢,需重头开始遍历,直到遍历到要查询的那一元素位置。但是插入速度非常快。
-
示例代码,这里只举linkList特有的方法。
public static void main(String[] args) { LinkedList<String>linkedList = new LinkedList<String>(); linkedList.add("test1");//添加 linkedList.add("test2"); linkedList.add("test3"); linkedList.add("test4"); linkedList.add("test5"); sop(linkedList); linkedList.addFirst("test6"); sop(linkedList); linkedList.addLast("test7"); sop(linkedList); //获取链表的头 sop(linkedList.element()); //获取第一元素 sop(linkedList.getFirst()); //获取最后一个元素 sop(linkedList.getLast()); //找到并移除此列表的头 System.out.println(linkedList.poll()); sop(linkedList); //找到并移除链表第一个元素 System.out.println(linkedList.removeFirst()); sop(linkedList); //找到并移除链表最后一个元素 System.out.println(linkedList.removeLast()); sop(linkedList); }
-
集
-
set元素是无序的,元素不可重复。
-
无序性:
-
当输入的值大小和底层数组大小差不多的时候,HashSet的输入顺序是无序的,但输出是有序的,因为这些数的哈希值,在底层是顺序拍的,故输出也是有序的。
public static void sop(Object o){ System.out.println(o); } public static void main(String[] args) { HashSet hashSet = new HashSet(); hashSet.add("java01"); hashSet.add("java02"); hashSet.add("java03"); hashSet.add("java04"); hashSet.add("java05"); hashSet.add("java06"); hashSet.add("java07"); sop(hashSet); }
[java07, java06, java05, java04, java03, java02, java01]
-
输入无序,而当输入的值大小和底层数组相差很大时,大的数的哈希值有可能是小于比他小的数的,这时候输出的结果就是无序的。
HashSet<Integer> hashSet = new HashSet(); hashSet.add(1); hashSet.add(10000000); hashSet.add(20); hashSet.add(123344); hashSet.add(9000); hashSet.add(122344); hashSet.add(234); sop(hashSet); Iterator<Integer> iterator = hashSet.iterator(); while(iterator.hasNext()){ System.out.print(iterator.next()+" "); }
[1, 123344, 20, 10000000, 9000, 122344, 234] 1 123344 20 10000000 9000 122344 234
-
-
HashSet
- 底层哈希表
- 没放一个
- 他的方法和list大同小异
- set是如何自动去重的
- 当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象也拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放进哈希表中,如果返回的是false,就会把这个值存放在哈希表中。
- 对象内容一样,哈希值是一样的。
- 底层哈希表
-
特殊
-
TreeSet:TreeSet 是一个有序的集合,它的作用是提供有序的Set集合。
-
LinkedHashSet(哈希链表): 查询慢,增删快。 有序的,存放顺序和取出顺序一致。
-
映射
- HashMap:key->value方式保存。key不允许重复。无序存放