Java——集合容器
来源:互联网 发布:vgg 网络结构 编辑:程序博客网 时间:2024/05/16 07:50
集合框架
集合类:
面向对象编程中会出现很多的对象,为了方便这些对象的存储,便出现了集合框架。集合框架可以存储和操作多个对象,而它和数组的不同是在于,数组只能存储同一类型的对象,而集合可以存储不同类型的对象,而且集合的长度可以是任意的。
集合框架中有很多中容器,用来存储对象。为什么会出现这么多容器呢?是因为每一个容器对对象的存储方式都不同,这种存储方式称为数据结构。
Collection类:
Collection
|--List//元素是有序的,元素可以重复。因为该集合体系有索引。
|--Set//元素是无序的,元素不可以重复。
|--List//元素是有序的,元素可以重复。因为该集合体系有索引。
|--Set//元素是无序的,元素不可以重复。
Collection类中常见方法:
添加元素
add(Object obj);
删除元素
remove(Object obj);
removeAll(集合);//删除参数集合中有的元素
clear();//清空集合
判断元素
contains(Object obj);//是否包含参数
isEmpty();//判空
获取集合长度
size();
取交集
retainAll(集合);//取和参数集合的交集
add(Object obj);
删除元素
remove(Object obj);
removeAll(集合);//删除参数集合中有的元素
clear();//清空集合
判断元素
contains(Object obj);//是否包含参数
isEmpty();//判空
获取集合长度
size();
取交集
retainAll(集合);//取和参数集合的交集
迭代器:
迭代器就是用来从集合中取出元素的方式。而迭代器被定义成内部类的形式,是因为Collection中有很多不同的子容器,这些子容器的数据结构不同,对元素的取出方式也不一样,但对外都提供了Iterator()方法进行取出操作。
迭代器的常见方法:
hasNext();//判断是否有下一个元素
next();//取出下一个元素
remove();//移除元素
next();//取出下一个元素
remove();//移除元素
遍历取出元素时,用循环判断hasNext()进行取出。推荐使用for循环,因为for循环中的迭代器是局部变量,循环后就会在内存中清除,写法如下:
for(Iterator it = a.iterator();it.hasNext(); ){ System.out.println(it.next());}
List类:
元素是有序的,元素可以重复。因为该集合体系有索引。
list类的特有方法:list类方法的特点是对索引进行操作。
增
add(index,element);//在指定位置添加元素
addAll(index,Collection);//在指定位置增加给定集合中的元素
删
remove(index);//删除指定位置的元素
改
set(index,element);//修改指定位置的元素。
查
get(index);//通过索引获取元素
subList(from,to);//获取子集的对象元素
add(index,element);//在指定位置添加元素
addAll(index,Collection);//在指定位置增加给定集合中的元素
删
remove(index);//删除指定位置的元素
改
set(index,element);//修改指定位置的元素。
查
get(index);//通过索引获取元素
subList(from,to);//获取子集的对象元素
List的三个子类
1. ArrayList
2.LinkedList
3.Vector
List集合判断元素是否相同,移除等操作,依据的是元素的equals方法。
ArrayList:
对应的数据结构是顺序表,查询速度快,增删速度慢。线程不同步。
Vector:
和ArrayList数据结构相同,因线程同步被ArrayList取代。
LinkedList:
对应的数据结构是链表,增删速度快,查询速度慢。
ListIterator:
它定义了针对于List数据结构的特有方法:
add(obj); //增加
set(obj); //修改为obj
hasPrevious(); //判断前面是否有元素
set(obj); //修改为obj
hasPrevious(); //判断前面是否有元素
Enumeration:
相当于Vector的迭代器。
特有方法:
addElement(obj);//相当于add(obj);
Enumerationelements();//Vector的取出元素方式
hasMoreElements();//相当于Iterator的hasNext()方法
nextElements();//相当于Iterator的next()方法
addElement(obj);//相当于add(obj);
Enumerationelements();//Vector的取出元素方式
hasMoreElements();//相当于Iterator的hasNext()方法
nextElements();//相当于Iterator的next()方法
LinkedList:
特有方法:因为链表增删操作繁琐,所以只有从头和从尾的增删方法。
增
addFirst();
addLast();
查
getFirst();
getLast();
删
removeFirst();
removeLast();
addFirst();
addLast();
查
getFirst();
getLast();
删
removeFirst();
removeLast();
查找和删除方法都会返回当前元素,如果没有获取到元素,则抛出NoSuchElementException。
在JDK1.6以后,出现了替代方法。
增
offFirst();
offLast();
获取
peekFirst();
peekLast();
删
pollFirst();
pollLast();
在JDK1.6以后,出现了替代方法。
增
offFirst();
offLast();
获取
peekFirst();
peekLast();
删
pollFirst();
pollLast();
同上,查找和删除方法都会返回当前元素,如果没有获取到元素,则返回null。
下面一个List集合的练习:
首先是LinkedList练习,用LinkedList实现队列和栈的存取操作。代码如下:
class MyQueue//队列结构元素存取顺序是FIFO(先进先出){private LinkedList link;public MyQueue(){link = new LinkedList();}public void push(Object obj){link.add(obj);}public Object pop(){return link.removeLast();}public boolean isNull(){return link.isEmpty();}}class MyStack//栈结构存取顺序是FILO(先进后出){private LinkedList link;public MyStack(){link = new LinkedList();}public void push(Object obj){link.add(obj);}public Object pop(){return link.removeFirst();}public boolean isNull(){return link.isEmpty();}}
Set类
在set集合中,元素是无序的,元素不可以重复。
常用的子类有两个:
HashSet,
TreeSet。
HashSet:
基于哈希表的Set集合,首先用hashcode()函数保证元素的唯一性, 如果hashcode的结果相同,则用equals()比较元素是否相同。
下面是HashSet存储自定义元素的程序示例:
import java.util.*;class Person//人类描述,存储的元素{private String name;private int age;Person(String name,int age){this.name=name;this.age=age;}public String getName(){return name;}public int getAge(){return age;}public boolean equals(Object obj){if(!(obj instanceof Person))return false;Person p=(Person)obj;return this.name.equals(p.name)&&this.age==p.age;}public int hashCode(){return this.name.hashCode()+this.age;}}class HashSetTest{public static void main(String[] args) {HashSet h=new HashSet();h.add(new Person("shenm",10));h.add(new Person("shenm2",6));h.add(new Person("shenm1",30));h.add(new Person("shenm0",10));h.add(new Person("shenm0",10));for (Iterator it=h.iterator(); it.hasNext(); )//取出元素{Person p=(Person)it.next();print(p.getName()+"..."+p.getAge());}}public static void print(Object obj){System.out.println(obj);}}
TreeSet:
基于的数据结构是二叉树,每次存入元素时对元素进行比较。比较的方法有二,一种是让元素自身具备比较性——就是实现Comparable接口,并覆盖CompareTo(Object obj)方法。第二种是自定义一个比较器类,实现Comparator接口,并覆盖Compare(Object o1, Object o2)方法。这两个函数的返回值是正数、负数、零,分别对应元素的比较结果为——大于、小于、等于。
下面给出两种比较方法的代码示例:
1、实现Comparable接口
class Person implements Comparable{private String name;private int age;public Person(String name, int age){this.name = name;this.age = age;}public String getName(){return this.name;}public int getAge(){return this.age;}@Overridepublic int compareTo(Object obj){if(!(obj instanceof Person))throw new RuntimeException("not a Person");Person p = (Person)obj;System.out.println(this.name + " compare to " + p.name);if(this.age > p.age)return 1 ;if(this.age == p.age)return this.name.compareTo(p.name);return -1;}}class TreeSetTest{public static void main(String args[]){TreeSet<Person> tr = new TreeSet<Person>();tr.add(new Person("zhangsan1", 11));tr.add(new Person("zhangsan2", 12));tr.add(new Person("zhangsan3", 13));tr.add(new Person("zhangsan4", 15));tr.add(new Person("zhangsan6", 19));tr.add(new Person("zhangsan5", 19));Iterator it = tr.iterator();while(it.hasNext()){Person p = (Person)it.next();print(p.getName() + "---" + p.getAge());}}public static void print(Object obj){System.out.println(obj);}}
2、自定义比较器实现Comparator接口
import java.util.*;class Person {private String name;private int age;public Person(String name, int age){this.name = name;this.age = age;}public String getName(){return this.name;}public int getAge(){return this.age;}}class TreeSetTest{public static void main(String args[]){TreeSet<Person> tr = new TreeSet<Person>(new PersonComparator());tr.add(new Person("zhangsan1", 11));tr.add(new Person("zhangsan2", 12));tr.add(new Person("zhangsan3", 13));tr.add(new Person("zhangsan4", 15));tr.add(new Person("zhangsan6", 19));tr.add(new Person("zhangsan5", 19));Iterator<Person> it = tr.iterator();while(it.hasNext()){Person p = (Person)it.next();print(p.getName() + "---" + p.getAge());}}public static void print(Object obj){System.out.println(obj);}}class PersonComparator implements Comparator<Person> { public int compare(Person p1,Person p2) { int num=new Integer(p1.getName().length()).compareTo(new Integer(p2.getName().length())); if (num==0) { return new Integer(p1.getAge()).compareTo(p2.getAge()); } return num; } }
Map类
Map类存放的元素是键值对,同时要保证键的唯一性。
Map类常见的子类有:
Hashtable
HashMap
TreeMap
Hashtable和HashMap都是基于哈希表的集合,HashMap较新,代替了Hashtable,允许存储null值和null键,线程不同步。
HashMap
TreeMap
Hashtable和HashMap都是基于哈希表的集合,HashMap较新,代替了Hashtable,允许存储null值和null键,线程不同步。
TreeMap是基于二叉树的集合。
Map类特有方法:
增:
put(K key,V value ) //添加元素
putAll(Map<? extends K , ? extends V> m ) //添加一组元素
删:
remove(Object key) //删除指定键值对
clear() //清空容器
查:
containsKey(Object key) //是否包含指定键
containsValue(Object value) //是否包含指定值
isEmpty() //判空
获取:
get(Object key) //通过键值获取对应的值
重要的是下面两个取出方法:
entrySet() //返回一个元素类型是Map.Entry<K, V>的Set集合,包含Map所有的键值对。
keySet() //返回一个包含map所以键值的Set集合。
在进行有关集合的练习时,应注意养成将元素都实现Comparable接口和自定义比较器的习惯。
下面是Map集合取出键值对的两种方式:
1、通过entrySet()方法直接返回包含键值对的Set集合:
代码如下:
示例Map的元素是自定义的学生类
import java.util.*;class Student implements Comparable<Student>{private String name;private int age;Student(String name, int age){this.name = name;this.age = age;}@Overridepublic int hashCode(){return name.hashCode() + age * 34;}@Overridepublic boolean equals(Object obj){if(!(obj instanceof Student))return false;//throw new ClassCastException("类型不匹配");Student s = (Student)obj;return this.name.equals(s.name) && this.age == s.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 String toString(){return "Student [name=" + name + ", age=" + age + "]";}@Overridepublic int compareTo(Student s){int num = new Integer(this.age).compareTo(new Integer(s.age));if(num == 0)return this.name.compareTo(s.name);return num;}}class MapTest2{public static void main(String[] args){TreeMap<Student, String> tm = new TreeMap<Student, String>(new StuNameComparator());tm.put(new Student("lisi03", 24), "武汉");tm.put(new Student("lisi01", 22), "北京");//tm.put(new Student("lisi01", 21), "天津");tm.put(new Student("lisi04", 23), "南京");tm.put(new Student("lisi02", 21), "上海");Set<Map.Entry<Student, String>> entrySet = tm.entrySet();Iterator<Map.Entry<Student, String>> it = entrySet.iterator();while(it.hasNext()){Map.Entry<Student, String> me = it.next();Student s = me.getKey();String addr = me.getValue();print(s + "--" + addr);}}public static void print(Object obj){System.out.println(obj);}}class StuNameComparator implements Comparator<Student>{public int compare(Student s1, Student s2){int num = s1.getName().compareTo(s2.getName());if(num == 0)return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));return num;}}
代码如下:(学生类定义部分不再给出)
class MapTest{public static void main(String[] args){HashMap<Student, String> hm = new HashMap<Student, String>();hm.put(new Student("lisi01", 21), "北京");hm.put(new Student("lisi01", 21), "天津");hm.put(new Student("lisi02", 22), "上海");hm.put(new Student("lisi03", 23), "武汉");hm.put(new Student("lisi04", 24), "南京");Iterator<Student> it1 = hm.keySet().iterator();while(it1.hasNext()){Student s = it1.next();String addr = hm.get(s);print(s + ".." + addr);}}public static void print(Object obj){System.out.println(obj);}}
Map扩展知识:
Map的映射关系不仅可以建立在单个元素之间,也可以建立在集合与元素,集合与集合之间,这样就形成了映射关系的嵌套。
比如传智播客体系,可以分为预热班,就业班,每个班中又有学生元素,学生可以有学号和姓名的映射关系。
给出代码示例:
import java.util.*;class MapExpandKnow{public static void main(String[] args) {//预热班HashMap<String,String> yureban=new HashMap<String,String>();//就业班HashMap<String,String> jiuyeban=new HashMap<String,String>();//传智播客HashMap<String,HashMap<String,String>> czbk=new HashMap<String,HashMap<String,String>>();czbk.put("yureban",yureban);czbk.put("jiuyueban",jiuyeban);//预热班级中学号与姓名的映射yureban.put("01","zhangsan");yureban.put("02","lisi");//就业班级中学号与姓名的映射jiuyeban.put("01","wangwu");jiuyeban.put("02","zhouqi");//直接显示全部学生信息getInfo(czbk);}//定义一个方法获取全部学生信息,包括在哪个班级,叫什么名字,学号多少public static void getInfo(HashMap<String ,HashMap<String,String>> hm){for (Iterator<String> it=hm.keySet().iterator();it.hasNext() ; ){String s= it.next();System.out.println(s+":");HashMap<String,String> stu=hm.get(s);getStuInfo(stu);}}//获取班级中学生的信息,包括姓名和学号public static void getStuInfo(HashMap<String,String> hm){for (Iterator<String> it=hm.keySet().iterator();it.hasNext() ; ){String key=it.next();//学号String value=hm.get(key);//姓名System.out.println(key+"..."+value);}}}
泛型
泛型是JDK1.5版本以后出现的新特性。用于解决安全问题,是一个类型安全机制。泛型要求在定义集合时,明确你要在集合中操作何种类型的数据,格式是通过<>来定义要操作的引用数据类型,如ArrayList<String>。这样就可以将运行时期出现的问题ClassCastException,转移到编译时期。方便于程序员解决问题。让运行时期问题减少、安全。同时也避免了强制转换的麻烦。当传入的类型不确定时,可以使用通配符?,也称为占位符。使用通配符的好处是可以不用明确传入的类型,这样在使用泛型类或者泛型方法时,提高了扩展性。
泛型限定:对泛型的上下限进行限定,明确泛型的范围。
<? extends E>:可接收E类型或E类型的子类型,称之为上限。
<? super E>:可接收E类型或E类型的父类型,称之为下限。
泛型类:当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展。现在定义泛型来完成扩展。
泛型方法:不同方法如果要操作不同类型的参数,而且类型还不确定,那么可以将泛型定义在方法上。
格式如下:
class Test<T>//泛型类{private T t;public void setObject(T t){this.t = t;}public T getObject(){return t;}//-----------------泛型方法public <E> void print(E e){System.out.println(e);}public <Q> void show(Q q){System.out.println(q);}}class GenericTest{public static void main(String[] args){Test<String> t = new Test<String>();t.setObject("GG");System.out.println(t.getObject());t.show(4);}}
0 0
- Java——集合容器
- Java集合——容器
- java的容器——集合
- 《Java编程思想》学习笔记4——集合容器
- Java基础——容器(集合初步)
- 黑马程序员——java中容器(集合类)
- 《Java编程思想》学习笔记4——集合容器 .
- 《Java编程思想》学习笔记4——集合容器
- 《Java编程思想》学习笔记4——集合容器
- 黑马程序员——java基础知识之集合框架(容器)
- 《Java编程思想》学习笔记4——集合容器
- 《Java编程思想》学习笔记4——集合容器
- 《Java编程思想》学习笔记4——集合容器
- Java容器集合学习心得
- Java容器集合学习心得
- Java容器集合学习心得
- Java容器集合学习心得
- C++容器 java集合
- excel编辑
- android studio grandle多渠道打包
- Android Studio 修改SDK路径
- windows2003查看文件被哪个进程占用
- 背包问题。
- Java——集合容器
- android中用jsonObject解析json数据
- 将字符串中进行反转。
- leetcode-80 Remove Duplicates from Sorted Array II
- sqldirect调用sql server存储过程demo
- oracle 12c安装时没有修改sys口令,网页管理无法登录
- qt编译错误的处理
- ajax和原生js比较与理解
- hdu 4704 费马小定理+快速幂