集合类 & MAP & 泛型
来源:互联网 发布:seo 刷关键词排名工具 编辑:程序博客网 时间:2024/06/06 17:28
可以看看这两篇博文
http://www.cnblogs.com/mingcn/archive/2010/10/22/JavaContainer.html
http://michaelfly.iteye.com/blog/519484
1.集合类的由来
对象用来封装各种不同的数据,比如person类里装了 string类型的name,int型的age
但是对象多了咋办,就用集合类来装,person1、person2.。。
2.集合的特点
集合容器只能用来存储对象,注意与数组的区别,数组也可以存储对象,但是数组还能存储基本数据类型。
集合的长度是可变的,随便你加减操作。而数组是一定的
3.不同集合的共性
不同集合容器内部的数据结构不同,所以有所区别,但是他们肯定有共性
往上抽取,就形成一些共性的框架
最基本的就是collection接口,里面有各种添加删除判断获取等方法
注意迭代器,iterator,取出集合里的元素,返回的是一个迭代器对象,用来取出集合里的对象
4.常用集合类容器,比如arraylist,collection的实现类
打印这个arraylist的时候,会打印出其中的所有元素
removeall移除相同的元素,retainall 保留相同的元素
迭代器的使用
hasnext,当还有元素可取时,返回true
next(),下一个元素
public class Hello { public static void main(String[] args){Collection col = new ArrayList();col.add("abc1");col.add("abc2");col.add("abc3");Iterator it = col.iterator();while(it.hasNext()){System.out.println(it.next());} }}
abc1abc2abc3
优化:这里循环结束了,iteratr还在,next()这个指向下一个的指针还在,占了一点内存,可以利用for循环来写,循环结束就销毁了,这种写法更常见
public static void main(String[] args){Collection col = new ArrayList();col.add("abc1");col.add("abc2");col.add("abc3");for(Iterator it = col.iterator();it.hasNext();){System.out.println(it.next());}
最常用的两个子接口:list和set
list是有序的-存入和取出的顺序是相同的,list有索引,list允许重复
set是hashmap的变种。为了让单列集合元素唯一,不允许重复
关于list的取出方式,除了collection通用的方式(set只有这个),还可以通过遍历位置信息去
demo:给list某个元素后加一个元素,如果list里没有这个元素,则输出整个list
public class Hello { public static void main(String[] args){ List list = new ArrayList(); list.add("abc1"); list.add("abc2"); list.add("abc3"); Iterator it = list.iterator(); while(it.hasNext()){ //add加的是对象,这里返回的应该也是对象 //开始读取 Object obj = it.next(); if(obj.equals("abc2")){ list.add("abc5"); }else {System.out.println("next:"+obj);} } System.out.println(list); }}
这个时候会报错,打印了第一个元素,然后挂了
为啥呢,因为往list里添加了元素,而iterator不知道
这里不能直接通过list添加,而可以通过列表迭代器来,只有list有一个单独的迭代器
public class Hello { public static void main(String[] args){ List list = new ArrayList(); list.add("abc1"); list.add("abc2"); list.add("abc3"); //不能在迭代器内用list来操作元素 ListIterator it = list.listIterator(); while(it.hasNext()){ //add加的是对象,这里返回的应该也是对象 //开始读取 Object obj = it.next(); if(obj.equals("abc3")){ //通过listIterator来迭代 it.add("abc6"); }else {System.out.println("next:"+obj);} } System.out.println(list); }}
5.list常用对象 arraylist,linkedlist,vector
vector出现的最早,内部是一个数组,但是可变大小,同步的,创建一个数组,将原来的东西复制进来,100%延长,增删查询都慢
arraylist用来代替vector,内部也是数组,可变大小,不同步的,他是在原有数组上延长,是50%的延长,更省事,关于不同步,上面的例子就很好的说明了,查询快
linkedlist,内部是链表,非同步的,增删元素比较快
6.MAP 和collection是一个级别的接口
但他是键值对,和collection最大的区别
put方法,返回的是之前key对应的value值,第一次存返回的就是null,或者说之前没有值,就是空
常用的实现类 hashmap
Map<Integer, String> map = new HashMap<Integer, String>();
想要取值,可以先找到所有key
6.1 通过getSet获得所有key的set集合,再通过set的迭代器获取每一个键,再通过键获取value
Map<Integer, String> map = new HashMap<Integer, String>(); //获得所有键的set集合 Set<Integer> keyset = map.keySet(); //通过set集合获得迭代器 Iterator<Integer> its = keyset.iterator(); while(its.hasNext()){ //通过迭代器取键 Integer key = its.next(); //通过键取值 String value = map.get(key); System.out.println(key+":"+value); }
6.2 entrySet 返回的是键值关系的set集合,通过把map转成Set,就能拿到一个迭代器,entrySet将映射关系作为对象存储到集合中,而这个映射关系类型是map.entry型
Map<Integer, String> map = new HashMap<Integer, String>(); Set<Map.Entry<Integer, String>> entryset = map.entrySet(); Iterator<Map.Entry<Integer, String>> itss = entryset.iterator(); while(itss.hasNext()){ Map.Entry<Integer, String> me = itss.next(); Integer key = me.getKey(); String value = me.getValue(); System.out.println(key+" : "+value); }
map.entry是一个静态的内部接口,会随着map的加载而加载,entry是映射关系的对象,访问map里的键和值,封装在map内
6.3 values()
返回所有值的collection对象,键唯一,值不唯一
Map<Integer, String> map = new HashMap<Integer, String>(); Collection<String> values = map.values(); Iterator<String> itsss = values.iterator(); while(itsss.hasNext()){ System.out.println(itsss.next()); }
6.4 map的子类
hashtable:内部结构是哈希表,非空,类似于collection中的vector,最早一个,同步的
hashmap:内部是哈希表,允许null作为键值,不是同步的(collection里的set是由hashmap实现的,就是他的一个实例,不过为了保证单列集合的元素唯一性才有的set)
treemap:内部结构是二叉树,不同步,可以对map里的键进行排序
hashtable有一个子类,properties,很生猛,属性集,用来存储键值对型的配置文件,常见与IO结合使用
7.泛型
是一种安全机制,在容器集合里面很常见
对于一些类型不匹配而导致的运行时错误转到编译来发现,也无需强转类型了
当数据类型不是很确定的时候,就加上<>成为泛型,将需要的数据类型传入,其实就是一个参数范围,类似于方法里的形参
只要有带<>的类或者接口,就需要明确类型
运行时,泛型会被去掉,生成的class文件里不带泛型,此即泛型的擦除,为了去兼容运行时的类加载器
由于只在编译时会带上泛型,那么在运行过程中,这些对象都还是object类,这样在实际操作时,本来应该还需要强转,但是强转是由一定隐患的,所以有了补偿机制
,通过在运行时获取类型来强转
以treeset为例
public class Person { String name; int age;public Person() {super();// TODO Auto-generated constructor stub}public Person(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}
public class MyGenericDemo { public static void main(String[] args) { TreeSet<Person> ts = new TreeSet<Person>(); ts.add(new Person("lisi",20)); ts.add(new Person("wangwu",30)); ts.add(new Person("yamiedie",18)); ts.add(new Person("qinshou",60)); Iterator<Person> it = ts.iterator(); while(it.hasNext()){ Person p = it.next(); System.out.println(p); } }}
跑起来,挂了,为嘛子,因为treeset是二叉树结构的,需要比较,他有比较器的方法,compare和equal
Exception in thread "main" java.lang.ClassCastException: com.leo.bean.Person cannot be cast to java.lang.Comparable
应该在person类实现一个接口,compare,任何可比较的方法里都有这个接口
先按年龄排序,相等时按名字排序
这里用到了compareTo方法,他是按照第一个字符的ASC码比较,返回差值
public class Person implements Comparable<Person>{ String name; int age;public Person() {super();// TODO Auto-generated constructor stub}public Person(String name, int age) {super();this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic int compareTo(Person p) {// TODO Auto-generated method stubint temp = this.age-p.age;return temp == 0?this.name.compareTo(p.name):temp;}}
while(it.hasNext()){ Person p = it.next(); System.out.println(p); System.out.println(p.toString()); System.out.println(p.getName()+":"+p.getAge()); }
<pre name="code" class="plain">com.leo.bean.Person@659e0bfdcom.leo.bean.Person@659e0bfdyamiedie:18com.leo.bean.Person@2a139a55com.leo.bean.Person@2a139a55lisi:20com.leo.bean.Person@15db9742com.leo.bean.Person@15db9742wangwu:30com.leo.bean.Person@6d06d69ccom.leo.bean.Person@6d06d69cqinshou:60
另一种比较的方法,equals(object o) 参数不能改类型的
通配符 ?
? extends 000 类型范围限制,表明只能接收000及他的子类
如何选择 集合容器
唯一?
需要 set
顺序?
需要 treeset
不需要 hashset
和存储一致:linkedhashset
不需要 list
需要频繁增删?
需要 linkedlist
不需要 arraylist
- 集合类 & MAP & 泛型
- Map集合(集合类)
- 集合类 Map集合
- 关于 泛型、map集合
- 泛型 Map集合(day18)
- 集合-map&&泛型
- 集合map、泛型
- 黑马程序员 泛型、Set集合类和Map集合类
- 黑马程序员---------泛型、Map集合、集合框架工具类
- java集合类Map
- java map集合类
- java Map集合类
- Collection Map 集合类
- 8.2集合类Map
- 集合类3-Map
- 集合类-Map
- Map.Entry类使用遍历Map集合
- java笔记-集合框架-泛型、Map集合
- DOS 批处理 知识点 MFC
- 编写spring配置文件时,不能出现帮助信息
- Leetcode 64(Minimum Path Sum)
- Ubuntu15.04 删除/sbin/upstart与孤儿进程收养的问题
- 华南运维论坛 2015-07-25
- 集合类 & MAP & 泛型
- 妆容之眼部
- pts 点云文件格式 最简便的点云格式
- windows下FileZilla使用sftp(SSH-2)
- C++第一天遇到的一下问题
- POJ 2236 Wireless Network
- Codeforces 558D - Guess Your Way Out! II (求区间交,并)
- JavaWeb学习笔记:Tomcat
- 虚基类