集合、泛型
来源:互联网 发布:如何建立图片数据库 编辑:程序博客网 时间:2024/06/06 14:26
集合
集合中存储的都是对象的引用(地址)
集合获取元素的方式:迭代器(iterator)
集合的理解:
java是一种面向对象语言,如果我们要针对多个对象进行操作,就必须对多个对象进行存储。
而对多个元素进行存储,前面我们学习过数组,数组的弊端,长度固定。这样,数组将不能
满足变化的要求。所以,java就提供了集合供我们使用。
集合的特点:
1、长度可以发生改变
2、只能存储对象
3、可以存储多种类型对象(一般存储的还是同一种)
集合和数组的区别
1、长度问题
数组固定
集合可变
2、存储元素问题
数组可以是基本类型,也可以是引用类型。
集合只能是引用类型。
3、是否同一类型
数组元素类型一致。
集合元素类型可以不一致。
4、集合体系的由来
集合是存储多个元素的容器,但是,由于数据结构不同,java就提供了多种集合类。
而这多种集合类有共性的功能,所以,通过不断的向上抽取,最终形成了集合体系结构。
集合框架:
1、长度可以发生改变
2、只能存储对象
3、可以存储多种类型对象(一般存储的还是同一种)
集合和数组的区别
1、长度问题
数组固定
集合可变
2、存储元素问题
数组可以是基本类型,也可以是引用类型。
集合只能是引用类型。
3、是否同一类型
数组元素类型一致。
集合元素类型可以不一致。
4、集合体系的由来
集合是存储多个元素的容器,但是,由于数据结构不同,java就提供了多种集合类。
而这多种集合类有共性的功能,所以,通过不断的向上抽取,最终形成了集合体系结构。
集合框架:
Collection接口:Collection接口是所有单列集合的父接口
|---list:元素是有序的,元素可以重复,因为该集合体系中有索引
|---ArrayList:底层使用的是数组结构,查询快,增删慢,判断元素唯一的方法是:equals 线程不同步
想建立自己特有的比较方式,只要在类中复写equals方法,建立子类特有的比较方式即可,使用contains方法,就会调用equals比较
|---LinkedList:底层使用的是链表结构。增删快,查询慢
|---Vector:底层使用的是数组结构,增删查都慢 线程同步
ArrayList和Vector的区别:
默认数组长度都为10,超出后,ArrayList每次增长50%,Vector每次增长100%
ArrayList和Vector都可以初始默认的长度
LinkedList的特有方法:
addFirst():向集合的开始位置追加元素
addLast():向集合的尾部位置追加元素
getFirst():获取集合的开始元素(获取元素,不删除,长度不变)
getLast():获取集合的尾部元素
如果集合中没有元素,会出现:NoSuchElementException异常(没有元素异常)
removeFirst():删除集合开始位置的元素(获取元素,删除元素,长度变化)
removeLast():删除集合尾部位置的元素
如果集合中没有元素,会出现:NoSuchElementException异常
JDK1.6版本以后出现了替代方法:
offerFirst()、offerLast()
peekFirst()、peekLast()如果集合中没有元素,返回 null
pollFirst()、pollLast()如果集合中没有元素,返回 null
对List集合的遍历:
1、for循环 for(int i =0;i<list.size();i++){ list.get(i) }
2、Iterator进行遍历
3、ListIterator列表迭代器
4、增强for循环
list 常用方法:
增:
add()
addAll()
删:
remove()
remove(位置):删除指定位置的元素
改:
set(位置,新值):将指定位置的值替换
查:
get(位置):获取指定位置上的元素
size():获取集合的大小
subList(起始位置,结束位置):获取包含头不包含尾的元素
indexOf():获取对象第一次出现的位置
lastIndexOf():获取元素最后一次出现的位置
Iterator():迭代器
hasNext()判断是否还有下一个元素
next()获取下一个元素
remove()删除元素
List集合特有的迭代器: ListIterator 它是 Iterator的子类接口
ListIterator():列表迭代器
add()插入
hasNext()正向判断是否还有下一个元素
hasPrevious()逆向遍历
next()返回下一个元素
previous()返回前一个元素
remove()删除元素
set()替换(修改)
package Demo;import java.util.*;class ListDemo {//输出方法public static void sop(Object obj){System.out.println(obj);}public static void method(){ArrayList al = new ArrayList();//添加元素al.add("java01");al.add("java02");al.add("java03");sop("原集合是:"+al);//在指定位置添加元素。al.add(1,"java09");//删除指定位置的元素。//al.remove(2);//修改元素。//al.set(2,"java007");//通过角标获取元素。sop("get(1):"+al.get(1));sop(al);//获取所有元素。for(int x=0; x<al.size(); x++){System.out.println("al("+x+")="+al.get(x));}Iterator it = al.iterator();//Iterator迭代器获取元素while(it.hasNext()){sop("next:"+it.next());}//通过indexOf获取对象的位置。sop("index="+al.indexOf("java02"));List sub = al.subList(1,3);sop("sub="+sub);}public static void main(String[] args) {//演示列表迭代器。ArrayList al = new ArrayList();//添加元素al.add("java01");al.add("java02");al.add("java03");sop(al);ListIterator li = al.listIterator();//sop("hasPrevious():"+li.hasPrevious());while(li.hasNext()){Object obj = li.next();if(obj.equals("java02"))//li.add("java009");li.set("java006");}//逆序遍历集合内容while(li.hasPrevious()){sop("pre::"+li.previous());}sop(al);}}
|--- set:元素是无序的(存入和取出的元素顺序不一致),元素不可以重复
---HashSet:内部数据结构是哈希表,判断元素唯一:HashCode和equals (默认长度:16)
(先判断哈希值是否相同,相同在比较两个元素的equals,如果相同,视为同一元素)
注意:对于判断元素是否存在,以及删除等操作,依赖的方法是:HashCode和equals方法
(先判断哈希值是否相同,不同,直接删除;相同在比较元素的equals,相同删除)
--- TreeSet:内部数据结构是二叉树,按照自然顺序存放。 (默认长度:空)
判断元素唯一的依据是:实现Comparable接口覆盖CompareTo方法,return返回0
(进行排序时,当主要条件相同,就按照次要条件进行排序,如果仍然相同,元素相同,不存)
可以对Set集合中的元素进行排序(内部是有序的,按照自然顺序存放)
TreeSet排序第一种方式:让元素自身具备比较性
实现Comparable接口,覆盖compareTo方法自然顺序排序
TreeSet排序第二种方式:让容器具备比较性
当元素自身不具备比较性时,或者具备的比较性不是想要的,
让集合自身具备比较性:定义一个比较器,将比较器对象作为参数传递给TreeSet集合
比较器:实现Comparator接口,覆盖compare方法
class MyCompare implements Comparator
{
public int compare(Object o1,Object o2){
}
}
让容器具备比较性:TreeSet ts=new TreeSet(new MyCompare)
当两种元素都存在时:以比较器为主
Set集合的迭代元素的方式:
1、Iterator迭代器
2、增强for循环
哈希表的原理:
1, 对对象元素中的关键字(对象中的特有数据),进行哈希算法的运算,并得出一个具体的算法值,这个值称为哈希值。
2, 哈希值就是这个元素的位置。
3, 如果哈希值出现冲突,再次判断这个关键字对应的对象是否相同。如果对象相同,就不存储,因为元素重复。如果对象不同,就存储,在原来对象的哈希值基础 +1顺延。
4, 存储哈希值的结构,我们称为哈希表。
5,既然哈希表是根据哈希值存储的,为了提高效率,最好保证对象的关键字是唯一的。 这样可以尽量少的判断关键字对应的对象是否相同,提高了哈希表的操作效率。
对于ArrayList集合,判断元素是否存在,或者删元素底层依据都是equals方法。
对于HashSet集合,判断元素是否存在,或者删除元素,底层依据的是hashCode方法和equals方法。
Set集合练习
向HashSet集合中学生对象,并且姓名和年龄相同的视为同一个人
class Demo{public static void main(String [] args){//创建HashSet对象HashSet<Student1> hs=new HashSet<Student1>();//向集合中添加学生对象hs.add(new Student1("lisi",10));hs.add(new Student1("wangwu",10));hs.add(new Student1("lisi",10));System.out.println(hs);}}//创建学生对象class Student1{private String name;private int age;Student1(){}Student1(String name,int age){this.name=name;this.age=age;}public void setName(String name){this.name=name;}public void setAge(int age){this.age=age;}public String getName(){return name;}public int getAge(){return age;}//复写toString方法public String toString(){return name+"="+age;}//复写HashCode和equals方法,保证元素唯一public int hashCode(){return this.name.hashCode()+age*3;}public boolean equals(Object obj){Student1 stu=(Student1)obj;return this.name.equals(stu.name) && this.age==stu.age;}}
Map集合(接口):
Map集合是双列集合的父接口
Map 集合的特点:集合中存储键值对,键和值一一对应,要保证键的唯一性(键值不能重复)
Map集合中的方法:
1、添加:
put(key,value):添加元素
当存储的键值相同时,新的值会替换旧值,并将旧值返回
如果键值没有重复,则返回null
putAll( Map< K , V >):添加一个集合元素
2、删除:
clear():清除
remove(Key):根据键,删除键值对 并将删除的值返回
3、判断:
containsKey(key):是否包含某个键
containsValue(Value): 是否包含某个值
isEmpty():判断是否为空
4、获取:
get(key):给定 键 ,返回对应的 值
size():获得Map集合中的键值对数
values():返回Map集合中所有的值,返回值为:Collection集合
Collection<> c = map.values()
重点:Map集合的遍历
entrySet():将Map集合的键值存入到Set集合
KeySet():将Map集合的键值存入到Set集合
Map:Set集合底层就是使用了Map集合
|--- Hashtable 底层是哈希表数据结构,线程同步,不可以存储null键和null值(默认长度:11)
|--- HashMap 底层是哈希表数据结构,线程不同步,可以存储null键和null值(默认长度:16)
作为键的自定义对象,必须实现HashCode方法和equals方法
|--- TreeMap底层是二叉树结构,进行自然顺序排序(默认长度:空)
可以对Map集合中的键进行指定顺序的排序
1、实现 comparable 接口,覆盖 compareTo 方法
2、让集合自身具备比较性:定义一个比较器,将比较器对象作为参数传递给TreeSet集合
比较器:实现Comparator接口,覆盖compare方法
class MyCompare implements Comparator{public int compare(Object o1,Object o2){}}//让容器具备比较性:TreeMap ts=new TreeMap(new MyCompare)
Map集合的两种取出方式:
1、keySet:将map集合中的所有键存入到Set集合中,因为Set具备迭代器
可以用迭代方式去除所有的键,在根据get方法获取每一个键对应的值
Map<String,String> mp = new HashMap<String,String>mp.put("","");Set<String> keySet=mp.KeySet(); //将Map集合的所有键存入到Set集合中Iterator < String > it = keySet.Iterator(); //利用Set集合的的Iterator迭代器获取到所有的键while(it.hasNext()){String key = it.next(); //得到所有的键String value = mp.get(key);//根据键得到Map集合中的所有值}
2、entrySet:将Map集合中的映射关系,存入到Set集合中
Map< String,String > mp = new HashMap< String,String >();mp.put("","");Set < Map . Entry< String,String > > entrySet = mp.entrySet(); //将map集合利用entry存入到Set集合中 类型为:Map . Entry类型Iterator < Map . Entry< String,String > > it=entrySet.iterator();//利用Set的迭代器,将Map集合的键值映射关系进行迭代while(it.hasNext()){Map.Entry< String,String > map=it.next();String key = map.getKey();//利用getKey方法取出键String value = map.getValue();//利用getValue方法取出值}
Map . Entry : 其实Entry也是一个接口,它是Map借口的一个内部接口
interface Map{ public static interface Entry{ public abstract Object getKey(); public abstract Object getValue(); }}
TreeMap存入自定义学生对象,实例:
将学生的姓名和年龄存入到Map集合中,并按照学生的年龄排序,如果年龄相等,按照姓名排序;姓名和年龄都相等视为同一个学生
public class Student {private String name;private int age;//空参构造函数public Student() {}//带参构造函数public Student(String name, int age) {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;}}<pre name="code" class="java">//将学生的姓名和年龄存入到Map集合中,并按照学生的年龄排序,如果年龄相等,按照姓名排序;姓名和年龄都相等视为同一个学生
public class TreeMapDemo{<span style="white-space:pre"></span>public static void main(String[] args) {<span style="white-space:pre"></span>// 创建集合对象,传入一个匿名对象比较器<span style="white-space:pre"></span>TreeMap<Student, String> tm = new TreeMap<Student, String>(<span style="white-space:pre"></span>new Comparator<Student>() {<span style="white-space:pre"></span>public int compare(Student s1, Student s2) {<span style="white-space:pre"></span>int num = s2.getAge() - s1.getAge();<span style="white-space:pre"></span>//1、按照年龄排序<span style="white-space:pre"></span>int num2 = (num == 0) ? s1.getName().compareTo(s2.getName()) : num;<span style="white-space:pre"></span><span style="font-family: 微软雅黑;">//2、按照姓名排序</span><span style="white-space:pre"></span>return num2;<span style="white-space:pre"></span>}});<span style="white-space:pre"></span>// 创建元素对象<span style="white-space:pre"></span>Student s1 = new Student("李世民", 30);<span style="white-space:pre"></span>Student s2 = new Student("朱元璋", 40);<span style="white-space:pre"></span>Student s3 = new Student("武则天", 50);<span style="white-space:pre"></span>Student s4 = new Student("武则天", 50);<span style="white-space:pre"></span>Student s5 = new Student("武则天", 30);<span style="white-space:pre"></span>// 添加元素<span style="white-space:pre"></span>tm.put(s1, "it001");<span style="white-space:pre"></span>tm.put(s2, "it002");<span style="white-space:pre"></span>tm.put(s3, "it003");<span style="white-space:pre"></span>tm.put(s4, "it004");<span style="white-space:pre"></span>tm.put(s5, "it005");<span style="white-space:pre"></span>// 遍历<span style="white-space:pre"></span>Set<Student> set = tm.keySet();<span style="white-space:pre"></span>for (Student key : set) {<span style="white-space:pre"></span>String value = tm.get(key);<span style="white-space:pre"></span>System.out.println(key.getName() + "***" + key.getAge() + "***"+ value);<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}}
工具类:
Collections:集合工具类,专用来对集合进行操作的
sort(List集合):对List集合进行排序
sort(List集合,new 比较器)
如果想按照自定的顺序进行排序,定义一个类实现Comparator接口,复写compare方法
max:获取集合中的最大值
binarySearch:对集合进行二分查找(只要是二分查找,就必须是有序的)
fill(集合,“字符串”):将集合中的元素全都替换为指定的字符串
replaceAll(集合,旧字符串,新字符串):将集合中的元素替换为指定元素
reverse(集合):将集合进行反转
reverseOrder(集合):返回一个比较器,将集合的(比较器的)顺序进行逆转
TreeSet ts = new TreeSet( Collections.reverseOrder( ) )(将集合进行逆序)
TreeSet ts = new TreeSet( Collections.reverseOrder( 自定义的比较器)) (将已有比较器进行逆转)
Arrays:数组工具类,专门用来对数组进行操作的工具类
asList:讲数组转换为list集合
binarySearch:数组二分查找
equals:判断两个数组是否相等
sort:对数组进行自然顺序排序
toString:将数组转换为字符串
Collection和Collections的区别:
Collection是java.util下的接口,单例集合的顶层接口,继承与它的接口主要有: List和set接口,它提供了关于集合的一些操作,如:添加、删除、遍历、判断一个元素是否是集合中的成员等 Collections是java.util下的一个更具类,它提供一系列的静态方法,实现了对集合的查找、排序sort、替换replaceAll等操作
集合那么多什么时候该用谁?
是否键值对?是:Map,是否对键排序?是:TreeMap否:HashMap不懂的情况就用HashMap
否:Collection,是否唯一?是:Set,是否对元素进行排序?是:TreeSet否:HashSet不懂的情况下,使用HashSet
否:List,是否要安全?是:Vector(真正开发中也不用)否:ArrayList,LinkedList
注意:
查询多:ArrayList增删多:LinkedList不懂的情况下,使用ArrayList
泛型:
JDK1.5以后出现的新特性,用于解决安全问题,是一个安全机制
泛型的好处:
1、将运行时期出现的问题,ClassCaseException(类型转换异常),转移到了编译时期,方便与程序员解决问题,让运行问题减少、比较安全!
2、避免了前置转换的麻烦
泛型的格式:通过<>来定义操作的引用数据类型
在使用java提供的对象时,什么时候写泛型?
通常在集合框架中很常见,只要见到 < > 就要定义泛型
< > 就是用来接收类型的
当使用集合时,将集合中要存储的数据类型作为参数传递到 < > 中即可
泛型类:
当类中要操作的引用数据类型不确定的时候,JDK1.4版本以前,用Object类完成扩展
JDK1.5版本以后,用 泛型 完成扩展
class Demo < T > { }
泛型类演示:
class Utils<QQ><span style="white-space:pre"></span>//泛型定义在类上{private QQ q;public void setObject(QQ q){this.q = q;}public QQ getObject(){return q; }}
泛型方法:
为了让不同方法可以操作不同类型,而且类型还不确定,就可以将泛型定义在方法上
public < T > void method ( T t ) { }
泛型方法示例
class Demo<T>{public void show(T t){System.out.println("show:"+t);}public <Q> void print(Q q)<span style="white-space:pre"></span>//泛型定义在方法上{System.out.println("print:"+q);}public static <W> void method(W w)<span style="white-space:pre"></span>//泛型定义在静态方法上{System.out.println("method:"+w);}}
静态方法泛型:(如果类中的静态方法需要泛型,那么泛型一定定义在方法上)
静态方法不可以访问类上定义的泛型
如果静态操作的引用数据类型不确定,那么可以将泛型定义在方法上
public static < T > void method ( T t ) { }
泛型接口:
interface Inter < T >{<span style="white-space:pre"></span>//泛型接口 void show ( T t )}
代码示例:
interface Inter<T><span style="white-space:pre"></span>//泛型接口{void show(T t);}class InterImpl<T> implements Inter<T><span style="white-space:pre"></span>//实现了接口的泛型类{public void show(T t){System.out.println("show :"+t);}}
用泛型有好出,可以限定传入的类型,但弊端是:泛型不明确,不能使用类型特有的方法
泛型的高级应用:泛型的限定,适用于泛型扩展(只能够使用父类中的方法)
? :占位符
< ? extends E > 可以接受 E 类型或者 E 类型的子类型 上限
< ? super E > 可以接受 E 类型或者 E 类型的父类型 下限
代码示例:
public static void printColl(Collection<? extends Person> al)<span style="white-space:pre"></span>//定义一个方法可以接受Person类和Person的子类{ Iterator<? extends Person> it = al.iterator(); while(it.hasNext()){ System.out.println(it.next().getName()); }}
0 0
- 集合,泛型
- 泛型&集合
- 集合、泛型
- 集合 --- 泛型
- 集合&泛型
- java笔记-集合框架-泛型、Map集合
- 集合(二)Map集合、泛型
- [泛型]集合Dictionary
- [泛型]集合Dictionary入门
- 数组/集合(ArrayList)/泛型
- 集合,泛型,各种遍历
- 黑马程序员---集合,泛型
- 集合框架《二》泛型
- 集合框架—泛型
- (17)集合&泛型
- 集合框架_泛型
- C#泛型Dictionary集合
- 关于 泛型、map集合
- Jsp抛出异常org.apache.jasper.JasperException
- 2012年5月SAT香港真题解析
- ios引导页图片尺寸
- 常用正则表达式
- GRE写作必备句型
- 集合、泛型
- 环信为自己的app加入即时通信功能的流程
- 【博客专家】新功能:优秀博文直推极客头条
- IO流(上)
- 【OpenCV】加载并显示图片
- NDK
- 最新最快BT5R3汉化方法
- 关于eclipse的汉化方法
- ubuntu14.04安装无线网卡驱动