黑马程序员_java_集合框架

来源:互联网 发布:cad制图软件学习 编辑:程序博客网 时间:2024/05/22 10:30

------- android培训、java培训、期待与您交流! ----------

【collection】


【List】

元素是有序的(加入的顺序),可以重复。因为该集合的集合体有索引。

--ArrayList 底层使用的是数组数据结构 特点:查询速度快,但是增删慢,线程不同步,线程不安全,效率高。特点:轻量级的用数组实现的(可以用下标进行删除和查                       查询快,增删慢(实现搜索引擎的最优选择)
--LinkedList 底层使用的是链表数据结构 特点:但是查询慢(实现栈的最优选择) 特有的addFirst()、removeFirst()方式
--Vector 底层是数组数据结构,和ArrayList 功能一样 但线程同步(安全) 增删查询都比较慢,被ArrayList替代
枚举是Vector的特有取出方式,类似迭代器,但方法名称过长

【Set】

元素无序,元素不可以重复。

①--Set:元素是无序的(存入和取出的顺序不一定一致,)元素不可以重复
        ②--HashSet:底层数据结构是哈希表;线程非同步
        ③--TreeSet;可以对Set集合中的元素进行排序 底层数据结构式二叉树
 保证元素唯一些的依据重写compareTo方法并return 0

Hashset保证元素唯一的逻辑

现在通过写一段代码来验证HashSet,对存入的对象时如何处理的
思路:

    1  新建一个HashSet,用来存储对象
    2  用add方法存入一个新的对象,这个对象有自己的属性:name和age
    3  通过查阅资料知道,HashSet在存入时如果 hash值相等时,就会调用Object的 equals 方法比较两个元素是否相等,
        具体 equals 比的是什么,要看具体的实现,但这里我们可以重写equals方法来自定义一个我们的比较方法。
    4 为了验证3的结论,我们通过public int hashCode方法,让对象拥有相同的哈希值。猜测:如果哈希值相同就会表用equals方法
         所以在public boolean equals(Object obj)中的“哈希值相同”就会打印出来。
    5  当哈希值相同了,我们可以自定义equals比较方法,如将姓名相同的视为一个人而不考虑年龄;或者将姓名年龄相同的视为一个人
问题:HashSet 判断元素是否存在也依赖于哈希值和equals方法

思路:用HashSet的contains方法判断person("a1",27)是否存在
 猜测:

①在自定义的equals()方法中只判断了姓名的时候person("a1",30)存在!
②在自定义的equals()方法中判断了姓名和年龄的时候person("a1",30)不存在!

class  HashSetDemo{public static void main(String[] args) {HashSet sh = new HashSet();sh.add(new person("a1",22));sh.add(new person("a1",29));sh.add(new person("a1",27));sh.add(new person("a4",24));sh.add(new person("a5",25));Iterator it = sh.iterator();while (it.hasNext()){ Object obj = it.next();//System.out.println(obj.name);}System.out.println(sh);//打印结果[person3c,person3c,person3c]System.out.println(sh.contains(new person("a1",30)));//当在equals()方法中只判断了姓名是否相同。所以在判断的时候就忽略了年龄。打印结果 ture     //当在自定义的equals()方法中判断了姓名和年龄的时候person("a1",30)不存在。打印结果 false}}class person { int age; String name;person(String name,int age){this.name = name;this.age = age;}public boolean equals(Object obj)//复写Object的equals 方法。{person p = (person) obj;System.out.println("哈希值相同");return this.name.equals(p.name);//&&this.age==p.age; //自定义比较的方法//理解:这里的this代表HashSet中已经存在的每一个对象,p代表存入的对象。}public int hashCode()//为对象设定哈希值,如果不设定,对象的哈希值就不相同,则equals方法就不会调用了。 {                return 60;   //设定每个对象的哈希值为60,而equals方法中的“哈希值相同”就会打印了。}public String setName(String name){this.name = name;return name;}public String getName(){return name;}public int getAge(){return age;}}
结论:在使用HashSet时,我们可以按照需求通过复写和equals()方法来自定义存储方式。

    HashSet 在判断元素是否存在也依赖于hashCode()和equals()方法。

特例:容器中装容器
每个Collecton都有一个addAll()方法,可以把一个集合完全装载到另外一个集合里面:例如:
Setset=newSet();Listls=newList();
Ls.addAll(set);//把Set装载在list里面。

Collections(工具类)
跟Collection没有关系,主要提供一些操作集合对象的方法。

List 底层使用的是数据结构,可以用迭代器遍历

迭代器(Iterator和ListIterator)

迭代器是是一种对象跟容器紧密结合,不同的容器,它的迭代器不同,但是,他们有共同的目标,就是可以通过该迭代器,来遍历访问这个容器里面的元素。

如果在迭代过程中要对元素进行增删功能就不能用容器的方法操作,那样会报错,只能用迭代器的方法操作,但不能用Iterator只能用迭代器的子接口ListIterator来操作。

import java.util.*;class listdemo{public static void main(String[] args) {ArrayList al = new ArrayList();al.add("java1");al.add("java2");al.add("java3");al.add("java4");al.add("java5");sop(al);Iterator it = al.iterator();//ListIterator li = al.listIterator();//Iterator子接口ListIteratorwhile (li.hasNext())//(it.hasNext()){Object obj = li.next();//it.next()if (obj.equals("java2")){/*al.add("java xxx000");//迭代过程中添加元素失败it.remove();//用迭代器的方法,当迭代到“java2”的时候删除这里的迭代器有局限性,没有添加的操作,只能用listIterarorli.add("java9");//在迭代到java2的时候添加“java9”li.set("java 007");//修改*/}}sop(al);}public static void sop(Object obj){System.out.println(obj);}}

加上泛型的迭代器及TreeSet的第一种排序方法:自定义比较器

class student{String name;student(String name){this.name=name;}public String getName(){return name;}}class advstudent extends student{advstudent(String name){super(name);}public String getName(){return name;}}class comp implements Comparator<student>//自定义比较器{public int compare(student s1,student s2)//覆盖compare方法{return s1.getName().compareTo(s2.getName());}}class studentdemo{public static void main(String[] args)   {TreeSet<student> ts = new TreeSet<student>(new comp());ts.add(new student("java1"));ts.add(new student("java2"));ts.add(new student("java3"));ts.add(new student("java4"));ts.add(new student("java5"));print(ts);TreeSet<advstudent> ts1 = new TreeSet<advstudent>(new comp());ts1.add(new advstudent("java...01"));ts1.add(new advstudent("java...02"));ts1.add(new advstudent("java...03"));ts1.add(new advstudent("java...04"));print(ts1);     }public static void print(TreeSet<? extends student> qqq)//传入带泛型限定的TreeSet{Iterator<? extends student> it = qqq.iterator();//迭代器加上了泛型,可以接受student及其子类while (it.hasNext()){System.out.println(it.next().getName());}}     }
TreeSet第二种排序方法:让元素具备比较性,复写compareto方法

public class Student implements Comparable{ private int num;  public int getNum() {   return num;  }  public void setNum(int num) {   this.num = num;  }  public int compareTo(Object obj) {   if (obj instanceof Student)   {    Student student = (Student)obj;    if (this.num > student.getNum())    {     return 1;    }    else if (this.num == student.getNum())    {     return 0;    }    else    {     return -1;    }   }   return 0;  }}

由集合排序引出的两个比较接口:

一个是Comparable:覆盖compareTo方法;(java.lang包中)

一个是Comparator:覆盖compare方法。(java.util包中)

使用集合的技巧:

看到Array就是数组结构,有角标,查询速度很快。

看到link就是链表结构:增删速度快,而且有特有方法。addFirst; addLast; removeFirst(); removeLast(); getFirst();getLast();

看到hash就是哈希表,就要想要哈希值,就要想到唯一性,就要想到存入到该结构的中的元素必须覆盖hashCode,equals方法。

看到tree就是二叉树,就要想到排序,就想要用到比较。

其实无论是自定义比较器还是让元素具备比较功能,都是集合底层在调用compare()或者compareto()方法,并使用return的数据来进行判定。

【MAP】


1:Map定义(key--value):通过一个key值得到一个value,一般用作八种基本类型和字符串作为一个map集合的key值,key值不能重复

2:SortedMap:一般是按照key值得升序排序,如果需要自己规定,那么就需要key对象所对应的类覆盖comparable接口。
3:HashMap(实现类):对key保持唯一。如果用自定义的key,那么就要覆盖hashclode()和equals()方法;
4:HashTable:(实现类):

5:二者比较:
HashMap轻量级的,线程不安全,键值可以有空指针。
HashTable:重量级的,线程安全的,键值都不能有空指针。

6:properties:

主要是用来存取配置文件的信息。本质上两个参数都是一个字符串型的。

获取map中的元素:

原理:map中是没有迭代器的,collection具备迭代器,只要将map集合转成Set集合,可以使用迭代器了。之所以转成set,是因为map集合具备着键的唯一性,其实set集合就来自于map,set集合底层其实用的就是map的方法。

map集合转成set的方法:

Entry就是Map接口中的内部接口;

为什么要定义在map内部呢?entry是访问键值关系的入口,是map的入口,访问的是map中的键值对。

--------------------------------------------------------

取出map集合中所有元素的方式一:entrySet()方法。

取出map集合中所有元素的方式二:keySet()方法。

import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;public class mapdemo {public static void main(String[] args){Map map = new HashMap();map.put("1", "abc");map.put("2", "abc");map.put("3", "abc");map.put("4", "abc");/*第一种取出方式Set set = map.entrySet();Iterator it = set.iterator();while (it.hasNext()){Map.Entry entry = (Map.Entry)it.next();System.out.println(entry.getKey()+"..."+entry.getValue());}*///第二种取出方式Set keys   = map.keySet();if (keys !=null);Iterator it = keys.iterator();while (it.hasNext()){Object obj = it.next();System.out.println(map.get(obj));}}}
资料:

Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。 从概念上而言,您可以将 List 看作是具有数值键的 Map。 而实际上,除了 List 和 Map 都在定义 java.util 中外,两者并没有直接的联系。

0 0