集合
-
集合常用操作的接口是List Set Map,和n个对应常用操作实现类
(1)泛型,jdk1.5之后的动态类型
(2)List Map set自身基本应用
(3)Index,hashcode 区别
(4)Iterator 迭代器,hashcode
(5)集合相互叠加泛型操作 List<Map<String,Object>>,类似二维数组
泛型
-
泛型:可以修改全局变量的类型,泛型类似一个形参,具体的type可以new对象赋值
-
赋值泛型的类型必须是引用类型,如果是基本那么赋值对应包装类
-
泛型是可以多个的,且可以是中文.如果new带泛型的类型,可以随意给泛型添加具体的类型,如果添加具体类型需要全部赋值,否则全部是object类型.如果不赋值类型,new对象默认警告黄线状态
-
泛型还可以给其限定类型,给泛型继承一个父类类型:
Fan<Y,好 extends Number>
Number是所有数值包装引用类型的父类,限定”好”泛型只能赋值具体的数值型.如果Fan所有泛型都不赋值,那么Y视为Object,好 视为Number类型
-
泛型代码:
package com.java.collections; /** * 泛型: * @author Administrator *关键的问题是,全局变量,要不是固定类型,要不是通用类型, *无法自定义类型,也就是new对象能改变的是value,无法灵活的改变type *Object全局变量类型无法修改new对象能够灵活的改变和自定义该全局变量的类型, *比如3个new对象,各自给age属性是3个type,如何设置 */ public class Fan<Y ,好 extends Number> { //创建一个类级别的全局变量,限定当前类的私有访问的属性,int类型名字age, //初始值是12的一个全局变量,or类属性。 // private int age=12; private Y age; private 好 name; public Fan() { // TODO Auto-generated constructor stub } public static void main(String[] args) { //还是默认给Y赋值的type是Object, Fan fa=new Fan(); //fa fa2 new对象的性质差异不大的。 // Fan<Object> fa2=new Fan<Object>(); //改变的是value,能改变type fa.age="false"; fa.name=23.5; //赋值Y是double // Fan<Double> fa1=new Fan<Double>(); // fa1.age=23.4; //如果添加具体类型,那么需要全部赋值,否则视为全部是object类型 Fan<String,Float> fa4=new Fan<String,Float>();//泛型 现阶段1.8的时候 后面的实例可以省略赋值泛型。 fa4.age=""; fa4.name=34.5f; //fa1 fa4和fa二者都是专属赋值了各自的类型的 Fan<String, Integer> f=new Fan(); } }
List
-
list:列表,和数组最接近的一个操作集合对象,存储是index索引
(1)ArrayList: 运行速度较快,缺点是无序的,无法去除重复的元素
(2)LinkedList:基本操作和ArrayList一样,Linked是链表的含义,是有序操作
-
参考代码:
package com.java.collections; import java.util.AbstractList; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ListsDemo { public ListsDemo() { // TODO Auto-generated constructor stub } public static void main(String[] args) { AbstractList list=new ArrayList(); list.add("a1");//默认index是0 list.add(12); list.add("a2");//2 list.add("a3");//实质根据该元素获取其地址,然后add具体的地址 list.add(13); list.add(1243); list.add("a3"); list.add(1223); list.add(183); list.add(193); list.add(1, "element");//"插队",插到第二个位置 list.add(223); list.add(323); for (int i = 0; i < list.size(); i++) { Object string = list.get(i); System.out.println(string); } System.out.println("-------------------"); /* * 删除list中的全部int Integer类型的所有元素 */ for (int i = 0; i < list.size(); i++) { Object string = list.get(i); if(string instanceof Integer) { list.remove(i); } } //删除后的结果,有"漏网之鱼",逻辑错误, for (int i = 0; i < list.size(); i++) { Object string = list.get(i); System.out.println(string); } /* * 案例,解决逻辑错误的,首先了解逻辑错误是什么 * 其次是3种方式,4个解决的方法 * 重点是两个方法,2个方面 */ } } //漏网之鱼解决方法: package com.java.collections; import java.util.AbstractList; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class ListsDemo { public ListsDemo() { // TODO Auto-generated constructor stub } public static void main(String[] args) { AbstractList list=new ArrayList(); list.add("a1");//默认index是0 list.add(12); list.add("a2");//2 list.add("a3");//实质根据该元素获取其地址,然后add具体的地址 list.add(13); list.add(1243); list.add("a3"); list.add(1223); list.add(183); list.add(193); list.add(1, "element");//"插队",插到第二个位置 list.add(223); list.add(323); for (int i = 0; i < list.size(); i++) { Object string = list.get(i); System.out.println(string); } System.out.println("-------------------"); /* * 删除list中的全部int Integer类型的所有元素 */ // for (int i = 0; i < list.size(); i++) { // Object string = list.get(i); // if(string instanceof Integer) { // list.remove(i); // } // } /* * 解决方案1:index解决,虽然得知index遍历的缺陷,但是通过该缺陷来继续index操作,避免问题出现 * index解决方法2种 * 方法1. i--,其实index缺陷是肯定的,但是操作的灵活也是必须的。 */ // for (int i = 0; i < list.size(); i++) { // Object string = list.get(i); // if(string instanceof Integer) { // list.remove(i); // i--;// 错过的int元素根据i的--,返回,也就是让for多循环一次 // } // } //方法2:还是利用index循环遍历,但是不用i--,倒叙 // for (int i = list.size()-1; i >=0; i--) { // Object string = list.get(i); // if(string instanceof Integer) { // list.remove(i); // } // } /* * 解决方案2, 不用index,hashcode方式解决,遍历代表就是Iterator */ //为什么集合遍历推荐用迭代器的方案原因了。避免无谓的逻辑错误。 // Iterator it=list.iterator(); // while (it.hasNext()) { // Object object = it.next(); // if(object instanceof Integer) { // //迭代器删除该集合的地址 // it.remove(); // } // } //迭代器遍历循环是随意的,通常用while 其次是for // for (Iterator iterator = list.iterator(); iterator.hasNext();) { // Object object = iterator.next(); // if(object instanceof Integer) { //迭代器删除该集合的地址 // iterator.remove(); // } // } //迭代器选择的循环,核心还是程序员的操作习惯。通常是while /* * 解决方案3,思路删除Integer类型元素,未必用remove方法 * 判断非Integer元素,add封装到一个新的集合对象中,over */ //删除后的结果,有"漏网之鱼",逻辑错误,index"迈过去"了,通过案例 for (int i = 0; i < list.size(); i++) { Object string = list.get(i); System.out.println(string); } } } package com.java.collections; import java.util.AbstractList; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Lists { public Lists() { // TODO Auto-generated constructor stub } public static void main(String[] args) { //常用2种list集合声明,集合实用操作方法都是雷同的。 // List<String> list1=new ArrayList<String>(); AbstractList<String> list=new ArrayList<String>(); list.add("a1");//默认index是0 list.add("a2");//2 list.add("a3");//实质根据该元素获取其地址,然后add具体的地址 list.add("a3"); list.add(1, "element");//"插队",插到第二个位置 // System.out.println("length:"+list.size()); // System.out.println("不支持模糊比对元素:"+list.contains("a")); // System.out.println("根据index获取元素:"+list.get(2)); // System.out.println("根据元素返回index "+list.indexOf("a1")); // System.out.println("删除元素:"+list.remove("element"));//删除的是元素所在的地址,不是元素本身 // System.out.println("删除元素:"+list.remove(2)); // System.out.println("根据index修改具体的元素值:"+list.set(2, "ele")); //遍历和[]是一样的模式,但是从集合的角度理解,遍历是有些不推荐的,推进迭代器方式。 //遍历实质是根据元素的地址去寻找value显示结果的过程。 // for (String string : list) { // System.out.println(":"+string); // } //推进的是迭代器方式遍历,while循环遍历更为广泛 //结果和for index遍历是一样的,但是有本质区别的。 // Iterator<String> itList=list.iterator(); // while (itList.hasNext()) { // String ele = itList.next(); // System.out.println(ele); // } } }
set
- Set :和List属于一个”家族”,所以相同之处是只有一个操作泛型
- set核心特点:
(1).hashcode存储方式和Map是一样的,不是list那样的index存储方式
(2).过滤重复的元素,长度显示全部都是不重复的元素
(3).Set应用比List少,因为hashcode存储方式不能类似list get那样根据条件获取其中一个元素这样便捷灵活的操作.这里体现hashcode操作不如index便捷.但是for (String string : set)能够逐个便利set集合元素.但是推荐用iterator
(4)Set集合因为如果index操作,有时候需要转换为[]操作,只能转换为Object[]
Map
-
Map 和List Set独立的另外一个操作对象”家族”,两个泛型,所以更多衔接的是ajax json
-
Map集合是既能够通过hashcode访问,每一个元素也能按照条件获取
-
Map集合是两个泛型,第一个是key,第二个是value,通过自定义的key,去访问对应的value
Key,value的具体应用需要hashcode,Map是key value模式, 通过key访问对应的value,实质是key去访问对应的16进制编码,然后访问对应的value
-
key不能重复,但是value可以, Size()过滤掉重复的key元素
-
Map集合常用的实现类是HashMap、LinkedHashMap、TreeMap、Hashtable
(1)HashMap:key,value都运行为null
HashMap的key Integer type,那么key是升序输出
(2)LinkedHashMap: key value都可以是null key是Integer类型不会排序,但是是有序输出,就是根据put的的顺序输出, 有序和排序是两个概念。
(3) TreeMap:key不允许null,value可以
关键是 key是升序输出
TreeMap和HashMap:区别key是否允许为null
(4) Hashtable:key value都不允许为null
总体还是按照put属性有序输出,有序的稳定性不如LinkedHashMap
该实现类是为列表服务的,所有都不允许有null值 -
map遍历的两种方式:
(1)遍历全部的key,然后通过key 访问value
因为iterator迭代器遍历只需要一个泛型,所以map集合不能直接赋值给iterator,只能借助于泛型的集合对象Set(虽然List也是一个泛型,但是不能用,因为list是index访问的)(2)直接遍历全部的value
-
map代码:
package com.java.collections; import java.util.*; public class Maps { public Maps() { } public static void main(String[] args) { Map<String, Double> map=new HashMap<String, Double>(); // map=new LinkedHashMap<String, Double>(); // map=new TreeMap<String, Double>(); // map=new Hashtable<String, Double>(); //put add的职能。 map.put("a1",123.34); map.put("a2",123.34); map.put("a3",143.34); map.put("a2",153.34);//同样的key覆盖之前的 System.out.println(map.get("a2")); System.out.println(map.size()); //Map集合的遍历是两组泛型 //遍历全部的key,然后访问value的形式需要借助于set集合 //Set<String> sets=map.keySet(); //map集合的所有key全部赋值给一个set集合对象 //因为迭代器不能直接交互map集合的key值,需要借助set集合 //set集合再转换为迭代器操作。 // Iterator<String> itMap=sets.iterator(); //省略的操作模式 // Iterator<String> itMap=map.keySet().iterator(); // while (itMap.hasNext()) { // String key = itMap.next(); // System.out.println(key+" - "+map.get(key)); // } //2.直接遍历全部的value,借助于collection接口 // Collection<Double> coll=map.values(); // Iterator<Double> val=coll.iterator(); Iterator<Double> itVal=map.values().iterator(); while (itVal.hasNext()) { Double double1 = itVal.next(); System.out.println(double1); } } }
-
代码二:
package com.java.collections; import java.util.*; public class Maps1 { public Maps1() { } public static void main(String[] args) { /*(1)**HashMap:key,value都运行为null** HashMap的key Integer type,那么key是升序输出 (2)**LinkedHashMap: key value都可以是null** key是Integer类型不会排序,但是是有序输出,就是根据put的的顺序输出, 有序和排序是两个概念。 (3) **TreeMap:key不允许null,value可以** 关键是 key是**升序**输出 TreeMap和HashMap:区别key是否允许为null (4) **Hashtable:key value都不允许为null** 总体还是按照put属性有序输出,有序的稳定性不如LinkedHashMap 该实现类是为列表服务的,所有都不允许有null值 */ Map<Integer, String> map=new LinkedHashMap();//<String, String> // map=new TreeMap<String, Double>(); // map=new Hashtable<String, Double>(); //put add的职能。 map.put(10,null); map.put(null,"z"); map.put(6,"b"); map.put(0,"c");//同样的key覆盖之前的。 //省略的操作模式 Iterator<Integer> itMap=map.keySet().iterator(); while (itMap.hasNext()) { Integer key = itMap.next(); System.out.println(key+" - "+map.get(key)); } } }
迭代器 Iterator
-
通过hashcode遍历,而不是index遍历的,Iterator专属集合遍历
-
集合的所有元素封装给迭代器对象,使用迭代器自身的遍历元素的hashcode存储方式进行读取显示的过程
-
代码:
package com.java.collections; import java.util.AbstractList; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; public class Lists { public Lists() { // TODO Auto-generated constructor stub } public static void main(String[] args) { //常用2种list集合声明,集合实用操作方法都是雷同的。 // List<String> list1=new ArrayList<String>(); AbstractList<String> list=new ArrayList<String>(); list.add("a1");//默认index是0 list.add("a2");//2 list.add("a3");//实质根据该元素获取其地址,然后add具体的地址 list.add("a3"); list.add(1, "element");//"插队",插到第二个位置 // System.out.println("length:"+list.size()); // System.out.println("不支持模糊比对元素:"+list.contains("a")); // System.out.println("根据index获取元素:"+list.get(2)); // System.out.println("根据元素返回index "+list.indexOf("a1")); // System.out.println("删除元素:"+list.remove("element")); //删除的是元素所在的地址,不是元素本身 // System.out.println("删除元素:"+list.remove(2)); // System.out.println("根据index修改具体的元素值:"+list.set(2, "ele")); // for (String string : list) { // System.out.println(":"+string); // } //迭代器方式遍历,while循环更为广泛 //结果和for index遍历是一样的,但是有本质区别的。 //把list集合的所有封装的地址,全部赋值给一个迭代器对象 // Iterator<String> itList=list.iterator(); // //把获取的list集合封装的所有元素的地址,进行改变存储方式,原来的index读取方式换成了hashcode方式。 // //循环遍历,判断该迭代器对象是否有下一个元素,如果有返回true,否则false // while (itList.hasNext()) { // //从迭代器中逐个获取每一个元素的地址对应的value // String ele = itList.next(); // System.out.println(ele+" - "); // } /* * 迭代器中每+itList.next()执行一次,那么迭代器对象都会遍历的元素下移一位,所以在一次循环中 * 两次next() 获取,所以一共5个元素中,第六次next()抛异常了。 */ AbstractList<String> listLink=new LinkedList<String>(); listLink.add("a1");//默认index是0 listLink.add("a2");//2 listLink.add("a3");//实质根据该元素获取其地址,然后add具体的地址 listLink.add("a3"); listLink.add(1, "element"); for (String string : listLink) { System.out.println(string); } } }
Index hashcode的区别
- Index:索引 C语言,Index标识每一个元素是有逻辑错误的隐患的
- 数组:超出长度需要重新声明一个新的数组,否则赋值不能超出之前赋值的长度
- 16进制编码是唯一的,和地址绑定,比index更加牢固,因为index比喻为门牌号,人离开,门牌号不会随着移动;hashcode是比喻成 “房卡”,人离开,房卡会跟随移动,房卡还是根据门牌号创建的一个唯一性的编码
集合相互叠加泛型
- List<Map<String,Object>>