Java学习笔记 (三)

Object类:完整的类最好覆写Object类的hashCode()equals()toString()3个方法。
在类集中提供了4种常见的输出方式:

  1. Iterator:迭代输出,使用最多的输出方式。
  2. ListIterator:Iterator的子接口,专门用于输出List中的内容。
  3. Enumeration:是旧接口,功能与Iterator类似。
  4. foreach:jdk1.5之后新增,输出数组和集合。
Iterator——迭代器:
  1. 二要素:
    i. 迭代器必定从属于某个容器,其作用就是用来遍历所属容器中的元素的。
    ii.迭代器是在容器的数据视图之上进行迭代,因此不能再迭代过程中修改容器中的数据,否则会抛出异常!除非使用迭代器的专用方法对数据进行修改。
  2. Java的迭代器只在Collection中有,而Map没有迭代器,它有不同的迭代方法。
  3. 迭代器的终极目标:就是用统一的方法来迭代不同类型的集合!可能由于不同集合的内部数据结构不尽相同,如果要自己纯手工迭代的话相互之间会有很大的差别,而迭代器的作用就是统一的方法对不同的集合进行迭代,而在迭代器底层隐藏不同集合之间的差异,从而为迭代提供最大的方便。
  4. 用迭代器迭代的步骤:
    i. 第一步肯定是先获取集合的迭代器:调用集合的iterator方法就能获得,Iterator<E> Collection.iterator(); // 是Collection的对象方法
    ii. 使用迭代器的hasNext、next往下迭代。
Iterator的常用方法:
* boolean hasNext(); // 是否还有下一个元素(肯定有一个位置指针维护者当前迭代的位置)
* Object next();        // 取出下一个元素并返回
* void remove();       // 从容器中删除当前元素(即上一个next代表的那个元素),直接会改变容器中的数据!  

 由于Java容器都是泛型类模板,因此容器可以记忆元素的具体类型,因此可以放心使用,只不过取出元素后要进行类型转换后才能正常使用,
使用迭代器next获得的元素是一个集合中对应元素的深拷贝(即数据视图),如果对迭代变量进行修改是不会修改集合中的原数据的。同样,也不能直接在迭代过程中使用c.remove等方法对集合进行修改,因为迭代器已经锁定住集合了,强行修改会抛出异常!只能用Iterator的专用修改集合元素的方法修改才是正确的,就像上面的Iterator.remove方法。
模板:

public class Test {  
      
    public static void main(String[] args) {  
        Collection c = new ArrayList(); // ArrayList是Collection的一个实现类,默认元素类型为Object  
          
        Iterator it = c.iterator();  
        while (it.hasNext()) {  
            Type var = it.next(); // 迭代值(数据视图)  
            对var进行操作;  
            c.remove(); // 错误!!在迭代过程中使用非迭代器方法对集合进行修改会直接抛出异常!!  
        }  
    }  
}  

实际上,Iterator迭代的“集合”是真正集合的视图,视图和真实数据之间是一一映射的关系,如果此时使用非迭代器方法对真实数据进行修改就会导致真实数据和映像之间不一致,因此会抛出异常,而迭代器的修改方法可以保证这种映射的一致性,即迭代器先对视图进行修改,然后将视图的修改更新到真实数据,但是反向就是无效的,因为映像自己是知道关联的是哪个真实数据,但是真实数据本身不知道有哪些映像和我关联的,即真实数据永远是被动的,而映像是主动的。

ListIterator

ListIterator是Iterator的子接口,专门用于输出List中的内容。只能从List接口实例化。可以进行双向迭代。

public class ListIteratorDemo01{
    public static void main(String argsp[]){
        List<String> all = new ArrayList<String>() ;
        all.add("hello") ;
        all.add("_") ;
        all.add("world") ;
        ListIterator<String> iter = all.listIterator() ;
        System.out.print("由前向后输出:") ;
        while(iter.hasNext()){
            String str = iter.next() ;
            System.out.print(str + "、") ;
        }
        System.out.print("\n由后向前输出:") ;
        while(iter.hasPrevious()){
            String str = iter.previous() ;
            System.out.print(str + "、") ;
        }
    }
};

输出结果:
由前向后输出:hello、、world、
由后向前输出:world、
、hello、

  • 在使用ListIterator接口进行双向输出时,如果想完成由后向前输出则一定要先进行由前往后输出。
  • foreach也可以输出集合。for(类 : 对象 集合)
  • Enumeration 废弃的接口,旧类,已被扩充。
Map接口
Map 图谱

Map 就是关联数组,也常被称为“映射表”或是“字典”,是键值对的集合容器,键不能重复出现是他的基本限制

如上图所示,Map 都继承自 Map 接口,标准 Java 类库中包含了几种 Map 的基本实现:

  1. TreeMap -- 基于红黑树的 Map 实现,因此是有序的,作为键加入 TreeMap 的对象必须实现 Comparable 接口,以便他可以被比较
  2. HashMp -- 基于哈希表的 Map 实现,虽然无序,但是优势却在于其查询速度
  3. LinkedHaskMap -- 在 HashMap 的基础上实现的双链表复合结构,在查询速度的基础上保证了插入顺序
  4. WeakHashMap -- WeakHashMap 与 HashMap 的用法基本相同,Hash 的 key 保留对象的强引用,即只要 HashMap 5. 对象不被销毁,其对象所有 key 所引用的对象不会被垃圾回收,HashMap 也不会自动删除这些key所对应的键值对对象。但 WeakHashMap 的 key 所引用的对象没有被其他强引用变量所引用,则这些 key 所引用的对象可能被回收。WeakHashMap 中的每个 key 对象保存了实际对象的弱引用,当回收了该 key 所对应的实际对象后,WeakHashMap 会自动删除该key所对应的键值对
  5. ConcurrentHashMap -- ConcurrentHashMap 保证了线程安全,一般用在多线程环境中
  6. IdentityHashMap -- 与 HashMap 一样,IdentityHashMap 也不保证存储的顺序,他与 HashMap 的区别在于,它用来比较键是否相同的方法是 == 而不是 equals 方法,因此值相同但地址不同的两个对象是允许出现的,一般只在解决特殊问题时才会使用

Map 接口定义了基本的 map 操作方法:

方法名 方法 说明
get V get(Object key) 获取 key 对应的值
put V put(K key, V value) 向容器中添加键值对
putAll void putAll(Map m) 将 Map m 中的所有元素添加到容器中
remove V remove(Object key) 删除指定的 key
clear void clear() 清除容器中所有元素
containsKey boolean containsKey(Object key) 判断 key 是否存在
containsValue boolean containsValue(Object value) 判断 value 是否存在
isEmpty boolean isEmpty() 判断容器是否为空
keySet Set keySet() 返回由所有 key 组成的 set
values Collection values() 返回由所有 value 组成的 Collection
entrySet Set> entrySet(); 获取 Map 内部接口 Entry 组成的 Set

TreeMap : String类型实现了comparable接口,如果使用自定义类的话需要先实现Comparable接口。
对象的四种引用方式:

  • 强引用
    强引用是最常见的的一种引用,类似"Object obj = new Object()"之类的引用,只要强引用还存在,垃圾收集器永远不会回收掉被引用对象。
  • 软引用 软引用是用来描述一些还有用但并非必需的对象。对于软引用的对象,在系统将要发生内存溢出之前,会把这些对象列入回收范围之中进行第二次回收。如果这次回收还没有足够的内存,才会抛出溢出异常。JDK1.2之后使用SoftReference来实现软引用。
  • 弱引用
    弱引用用来描述非必需的对象,但是强度比软引用更弱一些,被弱引用关联的对象只能生存到下一次垃圾收集器工作时,无论当前内存是否足够,都会回收弱引用所关联的对象。JDK1.2之后使用WeakReference来实现弱引用。
  • 虚引用
    虚引用又称幽灵引用或者幻影引用,他是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间存在影响,也无法通过虚引用来获取一个对象实例。为一个对象设置虚引用关联的唯一目的就是能在这个对象被收集器回收时收到一个系统通知。JDK1.2之后使用PhantomReference来实现虚引用。

总结:强引用的对象一定不会被当成垃圾回收的,软引用的对象会在内存不足时被当成垃圾回收掉,弱引用的对象在下一次垃圾回收时就直接回收掉。

Map接口的注意事项:

  1. 不能直接使用迭代(Iterator,foreach)输出Map中的全部内容。如果要用需按照以下4步。
    a. 将map的实例通过entrySet()方法变为Set接口对象。
    b. 通过Set接口实例为Iterator实例化。
    c. 通过Iterator迭代输出,每个内容都是Map.Entry的对象。
    d. 通过Map.Entry进行key→value的分离。
  • 使用Iterator输出Map实例
public class IteratorDemo04 {
    public static void main(String[] args) {
        Map<String, String> map = null;     // 声明Map对象,其中key和value的类型为String
        map = new HashMap<String,String>();
        map.put("lc", "lichuang");      // 增加内容
        map.put("jsf", "jisaifu");      // 增加内容
        map.put("wzc", "wangzhicheng");     // 增加内容
        Set<Map.Entry<String, String>> allSet = null;
        allSet = map.entrySet();
        Iterator<Map.Entry<String, String>> iter = null;
        iter = allSet.iterator();
        while (iter.hasNext()) {
            Map.Entry<String, String> me = iter.next();
            System.out.println(me.getKey() + "-->" + me.getValue());
        }
    }
}
执行结果:  
wzc-->wangzhicheng
lc-->lichuang
jsf-->jisaifu
  • 使用foreach输出Map实例:
public class ForeachDemo02{
    public static void main(String args[]){
        Map<String,String> map = null; // 声明Map对象,其中key和value的类型为String
        map = new HashMap<String,String>() ;
        map.put("lc", "lichuang");      // 增加内容
        map.put("jsf", "jisaifu");      // 增加内容
        map.put("wzc", "wangzhicheng");     // 增加内容
        for(Map.Entry<String,String> me:map.entrySet()){
            System.out.println(me.getKey() + " --> " + me.getValue()) ;
        }
    }
}

如果要使用一个自定义的对象表示Map中的key,则对象所在类中一定要覆写equals()和hashCode()方法,否则无法找到对应的value。

class Person{
    private String name ;
    private int age ;
    public Person(String name,int age){
        this.name = name ;
        this.age = age ;
    }
    public String toString(){
        return "姓名:" + this.name + ";年龄:" + this.age ;
    }
    public boolean equals(Object obj){
        if(this==obj){
            return true ;
        }
        if(!(obj instanceof Person)){
            return false ;
        }
        Person p = (Person)obj ;
        if(this.name.equals(p.name)&&this.age==p.age){
            return true ;
        }else{
            return false ;
        }
    }
    public int hashCode(){
        return this.name.hashCode() * this.age ;
    }
};
public class HashMapDemo08{
    public static void main(String args[]){
        Map<Person,String> map = null ;
        map = new HashMap<Person,String>() ;
        map.put(new Person("张三",30),"zhangsan");    // 增加内容
        System.out.println(map.get(new Person("张三",30))) ;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,565评论 18 399
  • java笔记第一天 == 和 equals ==比较的比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量...
    jmychou阅读 1,483评论 0 3
  • Java 面试题 整理自牛客网 什么是Java虚拟机?为什么Java被称作是“平台无关的编程语言”? Java虚拟...
    GuaKin_Huang阅读 10,657评论 19 265
  • 一本好书出现在你面前,肌肉包着骨头,衣服裹着肌肉,盛装而来。 你想读懂她,就要坦诚相见的态度,用心了解,虚心求教;...
    狷狂三斧阅读 2,669评论 31 128
  • 好久不见。 大概是因为心态发生了变化,很久没有在网上写字了,且不多说了。 近况困顿,友人奇葩君亦是如此。有很多想法...
    从前有块田阅读 181评论 0 0