您的位置:首页 > 编程语言 > Java开发

java基础—6.集合框架、泛型

2015-09-07 20:57 656 查看

一、理解及概述

集合可以看作是一个容器,集合类用于存储对象,并提供了相应的方法以便用户对集合进行:遍历、添加、删除以及查找对象。数组和集合的区别如下:|---数组 存储对象及基本数据,长度固定|---集合 只能存储对象,长度可变,不对存储基本数据类型

二、集合类的框架图



三、Collection接口——Set/List

|--Collection |----List 元素是有序的,元素可以重复,有索引(有类似的下标) |--ArrayList 底层的数据结构使用的是数组,查询快,增删慢,不支持枚举 |--LinkedList 底层使用的是链表数据结构,查询慢,增删快 |--Vector 底层是数组数据结构,线程同步,被ArrayList替代,支持枚举
|----Set  元素是无序的(指存入顺序),元素不可以重复
|--HashSet 底层数据结构是哈希表
HashSet通过元素的两个方法 ,HashCode和equals来完成,
(1)先比较hashCode(),再比较equals(),
(2)hashCode()不同,不调用equals()
|--TreeSet  可以对集合中的元素进行排序,
方法一:元素自身具备比较性Comparable接口——comparaTo()
方法二:定义一个比较器Comparator接口,new TreeSet(new Comparator())
|--Collection共性方法
|--添加 al.add()
|--打印 System.out.println(al);
|--删除 al.remove("java02");
|--长度 al.size();
|--判断 al.contains("java01");
al.isEmpty();
|--List/Set共性方法
|--增加  add(index,element);  addAll(index,Collection);
|--删除 remove(index);
|--改      set(index,element);
|--查       get(index)
sublList(from,to);
listIterator()
int indexOf(obj):获取指定元素的位置
ListIterator listIteratror();
|--List集合的测试代码:


package apiTest;
import java.util.*;

public class ListTest_1 {

public static void main(String[] args) {
arrayListTest();//arrayList测试的函数
linkedListTest();//LinkedList的测试函数
}
//arrayList测试的函数
public static void arrayListTest(){
//建立带泛型的ArrayList对象
ArrayList<Student> al = new ArrayList<Student>();
//存入对象
al.add(new Student("李四",001));
al.add(new Student("王五",002));
al.add(new Student("周七",003));
al.add(new Student("刘八",004));
//迭代器取出并打印(带上泛型,避免强转)
Iterator<Student> it =al.iterator();
while(it.hasNext()){
Student st =it.next();
System.out.println(st.getId()+"………………"+st.getName());
}
}
//LinkedList的测试函数
public static void linkedListTest(){
//建立带泛型的LinkedList对象
LinkedList<Student> al = new LinkedList<Student>();
//存入对象
al.add(new Student("李四",001));
al.add(new Student("王五",002));
al.add(new Student("周七",003));
al.add(new Student("刘八",004));
//迭代器取出并打印(带上泛型,避免强转)
Iterator<Student> it =al.iterator();
while(it.hasNext()){
Student st =it.next();
System.out.println(st.getId()+"………………"+st.getName());
}
}

}





|----Set的测试代码


package apiTest;
import java.util.*;
public class SetTest {

public static void main(String[] args) {
treeSetTest_1();//利用对象自身的比较性排序,对象类实现Comparable接口(ComparaTo方法)
treeSetTest_2();//利用自定义的比较器排序
hashSetTest();
}
//让元素自身比较性的TreeSet测试
public static void treeSetTest_1(){
//建立带泛型TreeSet集合,让元素自身比较
TreeSet<Student> ts = new TreeSet<Student>();
//一顿建对象和存对象
ts.add(new Student("lisi01",1));
ts.add(new Student("lisi02",2));
ts.add(new Student("lisi02",3));
ts.add(new Student("lisi01",1));//这条记录相同,存不了
//高级for循环遍历打印
for(Student s : ts){
System.out.println(s.getName()+"…………"+s.getId());
}
}
//让元素使用专门的比较器比较的
public static void treeSetTest_2(){
//建立带泛型TreeSet集合,传入比较器比较元素
TreeSet<Student> ts = new TreeSet<Student>(new Com());
//一顿建对象和存对象
ts.add(new Student("lisi01",1));
ts.add(new Student("lisi02",2));
ts.add(new Student("lisi02",3));
ts.add(new Student("lisi01",1));//这条记录相同,存不了
//高级for循环遍历打印
for(Student s : ts){
System.out.println(s.getName()+"*****"+s.getId());
}
}
//HashSet集合测试,元素要复写hashCode()、equals()方法
public static void hashSetTest(){
//建立HashSet对象,并定义Student泛型
HashSet<Student> hs = new HashSet<Student>();
//一顿建对象和存对象
hs.add(new Student("lisi01",1));
hs.add(new Student("lisi02",2));
hs.add(new Student("lisi02",3));
hs.add(new Student("lisi01",1));//这条记录相同,存不了
//高级for循环遍历打印
for(Student s : hs){
System.out.println(s.getName()+"&&&&&&&&"+s.getId());
}
}

}
//用于比较学生的比较器,并定义泛型
class Com implements Comparator<Student>{

@Override//重写compare方法
public int compare(Student o1, Student o2) {
//定义num记录名字顺序
int num = o1.getName().compareTo(o2.getName());
//名字相同时,比较学号
if(num==0){
return new Integer(o1.getId()).compareTo(new Integer(o2.getId()));
}
//返回结果
return num;
}

}
package apiTest;

class Student implements Comparable<Student>{
private String name;
private int id;

@Override//实现对象比较方法
public int compareTo(Student st) {
//先比较ID,再比较改名
if(this.id>st.id){
return 1;
}else if(this.id<st.id){
return -1;
}
return this.name.compareTo(st.name);
//也可以用下面简化的书写,但不方便阅读
//return this.id>st.id ? 1:(this.id<st.id ? -1:this.name.compareTo(st.name));
}
@Override//重写hashCode()
public int hashCode() {
return name.hashCode()+id*30;
}
@Override//重写equals()
public boolean equals(Object obj) {
if(!(obj instanceof Student))
return false;
Student stu = (Student)obj;
return this.name.equals(stu.name) && this.id == stu.id ;
}
//构造函数
public Student(String name, int id) {
this.name = name;
this.id = id;
}
// set/get方法
public String getName() {
return name;
}
public int getId() {
return id;
}

}


四、Map<K,V>接口—HashMap/TreeMap/Properties

|--Map<K,V>

|--HashMap 底层是哈希表数据结构,允许null值和键,线程不同步,jdk1.2,效率高
|--T
cd63
reeMap 底层是二叉树,可以给key排序
|--HashTable  和HashMap差不多,但是不允许存null值和键,线程同步jdk1.0
|--Properties 存储的键值对都是字符串,是集合中和IO技术结合的集合容器,用于配置
文件信息


|--Map<K,V>共性方法
|--添加
put(K key ,V value)
putAll(Map<? extends K,?  extends V> m )
|--删除
remove(Object key)
clear();
|--查询
get(Object key);
values()
size();
keySet();   //第一种取出方式
entrySet(); //第二种取出方式
|--判断
containsKey(Object key)
containsValue(Object value)
|--Properties 方法
|--加载入流


Properties prop = new Properties();
FileInputStream fis = new FileInputStream("info.txt");
prop.laod(fis);               // 将Properties数据加载到输入流中
prop.list(System.out); //将流中的Properties对象以列表形式打印


|--设置和获取


prop.setProperty("lisi",33+"");
String vaule= prop.getProperty("lisi");


|--存取


FileOutputStream fos = new  FileOutputStream("info.txt");
prop.store(fos."haha")


|--Map的测试
package apiTest;
import java.util.*;

public class MapTest {

public static void main(String[] args) {
//建立带泛型的HashMap集合
HashMap<String,Integer> hm = new HashMap<String,Integer>();
//存对象
hm.put("zhangsan", 1);
hm.put("wuliu", 2);
hm.put("lisi", 3);
hm.put("zhouba", 4);
//第一种keySet()取出打印,keySet()、get(key)
show_1(hm);
//第二种entrySet()取出打印Entry<k,v>
show_2(hm);
}
//用keySet()和get(key)取出元素的方式
public static <k,v> void show_1(HashMap<k,v> hm){
//1.得到Key的Set集合
Set<k> se= hm.keySet();
//2.迭代器关联
Iterator<k> it =se.iterator();
System.out.println("**********"+"keySet()取出方式"+"***********");
while(it.hasNext()){
k key = it.next();
//3.分别得到key和value
System.out.println(hm.get(key)+"…………"+key.toString());
}

}
//用Entry<k,v>取出元素
public static <k,v> void show_2(HashMap<k,v> hm){
//1.建立带Map.Entry<k,v>泛型的Set集合
Set<Map.Entry<k,v>> se =hm.entrySet();
//2.与迭代器关联
Iterator<Map.Entry<k,v>> it = se.iterator();
System.out.println("**********"+"这是entrySet()取出方式"+"**********");
while(it.hasNext()){
Map.Entry<k,v> me =it.next();
//3.分别得到key和value
System.out.println(me.getValue()+"…………"+me.getKey());
}
}

}


五、迭代器、高级for循环

|--迭代器:集合的取出元素的方式,每一个容器的取出方式不一样
Iterator<> it = collection.iterator();
while(it.hasNext())
{
s.o.p(it.next());
}
for(Iterator it = collection.iterator();it.hasNext();)  //内存中it及时消除,内存管理较好
{
s.o.p(it.next());
}
|--高级for循环:对for的增加强,只能取出不能修改 for(数据类型 变量名 : 被遍历的集合(Collection)或者数组) {}
String arr = {"ab","bc","cd"}
for(String s : arr)
{
System.out.println(s);
}

六、泛型

JDK1.5版本以后出现的新特性,用于解决安全问题,是一个安全机制。
|--好处:
1.可以将运行时期出现的ClassCastException,转移到了编译时期,方便于程序员解决问题。让运行事情问题减少、安全
2.避免了强制转换麻烦
|--定义格式: <> 如: TreeSet <String> ts = new TreeSet<String>();
如 :class LenComparator implements Comparator<Student>{}
当使用集合时,<>用于定义接收的元素类型
|--泛型运用
|--泛型类 :当类中要操作的引用 数据类型不确定的时候
class Demo<E>{}
|--泛型方法 :减少方法的重载,一定关注作用域
class Demo<T> //全类共用的泛型
{
public void show (T t){}
public void print(T t){}
}
class Demo2{
public <T> void show(T t){} //两个方法是局部的,可以分别指定类型
public <T> void print(T t){}
}
|--静态方法泛型 一定要关注到,静态的方法不能访问类上定义的泛型,只能定义到方法上
class Demo3<T>
{
//以下是错误的
// public static void method(T t){}
//以下是对的,注意顺序
public static <W> void method(W w){}
}
|--泛型接口
interface Inter<T> { void show (T t);}
class InterImpl implements Inter<T>
{
public void show(T t)
{
s.o.p(t)
}
}
|--泛型限定
(1)<?> 通配符 ,不明确具体类型的情况下
如:public static void printColl(ArrayList<?> al)
(2)<? extends Person> 明确集合容器的存取类型,限定上限
如 class Person
class Student extends Person
class worker extends Person
public static void printColl ( ArrayList <? extends Person> al)
(3)<? super Student> 明确集合容器的存取类型,保证安全,明确下限,为了增加扩展 性


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java java基础