当前位置: 代码迷 >> 综合 >> 容器(Queue/Deque/Enumeration/Hashtable/Properties等)
  详细解决方案

容器(Queue/Deque/Enumeration/Hashtable/Properties等)

热度:63   发布时间:2024-01-09 19:14:15.0

一、队列(Queue/Deque)
Queue:单向
队列通常FIFO(先进先出)、优先级队列和堆栈队列(后进先出)

add         增加一个元索              如果队列已满,则抛出一个IIIegaISlabEepeplian异常
remove      移除并返回队列头部的元素    如果队列为空,则抛出一个NoSuchElementException异常
element     返回队列头部的元素           如果队列为空,则抛出一个NoSuchElementException异常
offer       添加一个元素并返回true       如果队列已满,则返回false
poll        移除并返问队列头部的元素    如果队列为空,则返回null
peek        返回队列头部的元素           如果队列为空,则返回null

Deque:双向
此接口扩展了Queue接口,在将双端队列用作队列时,将得到FIFO(先进先出)
可用作LIFO(后进先出)堆栈

package Queue;import java.util.ArrayDeque;
import java.util.Queue;
/*** 模拟银行排队情况* @author liguodong*/
public class Demo01 {
    public static void main(String[] args) {Queue<Request> que = new ArrayDeque<>();        for(int i=0;i<10;i++){final int num = i;//每次进行这个循环时num都会重新被声明。que.offer(new Request() {   @Overridepublic void deposit() {//匿名内部类只能访问final修饰的对象System.out.println("第"+num+"个人,办理存款业务,存款额度为"+(Math.random()*10000));}});}dealWith(que);}//处理业务public static void dealWith(Queue<Request> que){Request req = null;while(null!=(req=que.poll())){req.deposit();}}
}interface Request
{//存款void deposit(); 
}

运行结果:

第0个人,办理存款业务,存款额度为2735.6735098014296
第1个人,办理存款业务,存款额度为7962.567153968527
第2个人,办理存款业务,存款额度为3171.5882900429524
第3个人,办理存款业务,存款额度为7139.268433521327
第4个人,办理存款业务,存款额度为1232.7711791595996
第5个人,办理存款业务,存款额度为1965.2528750898402
第6个人,办理存款业务,存款额度为9290.225524643947
第7个人,办理存款业务,存款额度为6937.284692790916
第8个人,办理存款业务,存款额度为7716.553752322355
第9个人,办理存款业务,存款额度为5789.095566314259
package Queue;import java.util.ArrayDeque;
import java.util.Deque;/*** 使用双向队列实现自定义堆栈* 1.弹* 2.压* 3.获取*/
public class MyStack<E> {//容器private Deque<E> container  = new ArrayDeque<E>();//容量private int cap;public MyStack(int cap){super();this.cap = cap;     }   //压栈public boolean push(E e){if(container.size()+1>cap){return false;}return container.offerLast(e);}   //弹栈public E pop(){return container.pollLast();}//获取public E peek(){return container.peekLast();}public int size(){return this.container.size();}
}
package Queue;public class Demo02 {public static void main(String[] args) {MyStack<String>  backHistory = new MyStack<String>(3);backHistory.push("www.baidu.com");backHistory.push("www.google.com");backHistory.push("www.sina.com");backHistory.push("www.tenxun.com");System.out.println("大小:"+backHistory.size());       //遍历String item = null;while(null!=(item=backHistory.pop())){System.out.println(item);}}
}

运行结果:

大小:3
www.sina.com
www.google.com
www.baidu.com

二、Enumeration
比较古老的接口
枚举Enumeration,作用和Iterator类似,都是输出数据。
方法:

hasMoreElements() nextElement()
package Enumeration;import java.util.Enumeration;
import java.util.Vector;/*** Enumeration使用* 1.判断 hasMoreElement()* 2.获取 nextElement()* * Vector的elements()方法*/public class Demo01 {
    public static void main(String[] args) {Vector<String> vector = new Vector<>();vector.add("javase");vector.add("html");vector.add("oracle");//遍历该Vector//public Enumeration<E> elements() JDK里该方法使用的匿名内部类对其进行实现Enumeration<String> en = vector.elements();while(en.hasMoreElements()){System.out.println(en.nextElement());}}
}

运行结果:

javase
html
oracle
package Enumeration;import java.util.StringTokenizer;/*** Enumeration子类* StringTokenizer与String的split()方法相类似,用于字符串分割* StringTokenizer不支持正则表达式,split()支持正则表达式*/
public class Demo02 {
    public static void main(String[] args) {String emailStr = "liguodong@163.com;liguodong@qq.com;liguodong@sohu.com";      //遍历获取//public class StringTokenizerextends Object implements Enumeration<Object>StringTokenizer token = new StringTokenizer(emailStr,";");while(token.hasMoreElements()){System.out.println(token.nextElement());}       }   
}

运行结果:

liguodong@163.com
liguodong@qq.com
liguodong@sohu.com

三、Hashtable
(一)Hashtable与HashMap的区别
1、
Hashtable线程安全,同步,效率相对低下。
HashMap线程不安全,非同步,效率相对高。
2、父类不同

public class HashMap <K,V>extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable public class Hashtable<K,V>extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable

3、null值
Hashtable的键与值都不能为null
HashMap的键最多一个null,可以与多个null。

(二)Properties
public class Properties extends Hashtable<Object,Object>
作用:读写资源配置文件
要求:键与值只能为字符串
方法:

Object setProperty(String key, String value)  调用 Hashtable的方法put。 String getProperty(String key) 用指定的键在此属性列表中搜索属性。String getProperty(String key, String defaultValue) 用指定的键在属性列表中搜索属性。  

后缀:.properties

void store(OutputStream out, String comments) 
以适合使用 load(InputStream) 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。 void store(Writer writer, String comments) 以适合使用 load(Reader) 方法的格式,将此 Properties 表中的属性列表(键和元素对)写入输出字符。 void load(InputStream inStream) 
从输入流中读取属性列表(键和元素对)。 void load(Reader reader) 
按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。 

后缀:.xml

void storeToXML(OutputStream os, String comment)  
发出一个表示此表中包含的所有属性的 XML 文档。 void storeToXML(OutputStream os, String comment, String encoding)  
使用指定的编码发出一个表示此表中包含的所有属性的 XML 文档。 void loadFromXML(InputStream in) 
将指定输入流中由 XML 文档所表示的所有属性加载到此属性表中。 
package Hashtable;import java.util.Properties;/*** Properties资源配置文件的读写* 1.key与value只能字符串* 2.存储于读取* setProperty(String key,String value)* getProperty(String key,String defaultValue)*/
public class Demo01 {
    public static void main(String[] args) {//创建对象Properties pro = new Properties();//存储pro.setProperty("driver", "oracle.jdbc.driver.OracleDriver");pro.setProperty("url", "jsbc:oracle:thin:@localhost:1521:orcl");pro.setProperty("user","scott");pro.setProperty("pwd", "tiger");        //获取url,如果没有返回test。String url=pro.getProperty("url", "test");System.out.println(url);}
}

运行结果:

sbc:oracle:thin:@localhost:1521:orcl

(三)相对路径与绝对路径

package Hashtable;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;/***使用Properties输出到文件*资源配置文件:*1、.properties*store(OutputStream out,String comments)*store(Writer writer,String comments)*2、.xml*storeToXML(OutputStream out,String comments) UTF-8字符集*storeToXML(OutputStream out,String comments,String encoding)*/public class Demo02 {
    public static void main(String[] args) {//创建对象Properties pro = new Properties();//存储pro.setProperty("driver", "oracle.jdbc.driver.OracleDriver");pro.setProperty("url", "jsbc:oracle:thin:@localhost:1521:orcl");pro.setProperty("user","scott");pro.setProperty("pwd", "tiger");        //1、绝对路径:带盘符 存储到d:/others try {pro.store(new FileOutputStream(new File("d:/others/db.properties")),"db配置");pro.storeToXML(new FileOutputStream(new File("d:/others/db.xml")),"db配置");} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}//2、使用相对路径 默认是当前的工程try {pro.storeToXML(new FileOutputStream(new File("db.xml")),"db配置");pro.store(new FileOutputStream(new File("src/Hashtable/db.properties")),"db配置");    //pro.store(new FileOutputStream(new File("db.properties")),"db配置");System.out.println("完成");} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}
package Hashtable;import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;/*** 使用Properties读取配置文件* 资源配置文件* load(InputStream inStream)* load(Reader reader)* loadFromXML(InputStream in)*/public class Demo03 {
    public static void main(String[] args) {Properties pro = new Properties();try {//读取 绝对路径//pro.load(new FileReader("d:/others/db.properties")); //读取 相对路径//pro.load(new FileReader("db.xml"));pro.load(new FileReader("src/Hashtable/db.properties"));} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}System.out.println(pro.getProperty("pwd", "sclgd"));//pro.list(System.out);}
}

运行结果:
tiger

(四)类路径加载资源文件

类所在的根路径
Demo04.class.getResourceAsStream("/")
Thread.currentThread().getContextClassLoader().getResourceAsStream("")
package Hashtable;import java.io.IOException;
import java.util.Properties;/*** 使用类相对路径读取配置文件*/public class Demo04 {
    public static void main(String[] args) {Properties pro = new Properties();      try {//类相对路径 /表示 bin//pro.load(Demo04.class.getResourceAsStream("/Hashtable/db.properties"));//类相对路径 ""表示 binpro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("Hashtable/db.properties"));} catch (IOException e) {e.printStackTrace();}System.out.println(pro.getProperty("user", "fuck"));}
}

运行结果:
scott

四、引用分类:
强引用:StrongReference 引用指向对象,gc(Garbage collection)运行时不回收。
软引用:SoftReference 运行时可能回收(jvm内存不够)
弱引用:WeakReference gc运行时立即回收
虚引用:PhantomReference类似于无引用,主要跟踪对象被回收的状态,不能单独使用,必须与引用队列(ReferenceQueue)联合使用。

目的:避免对象长期驻留在内存中,解决垃圾回收机制回收时机问题。

WeakHashMap
键为弱引用,回收键后自动删除(key,value)对象。

IdentityHashMap
键比较,地址去重,而不是比较hashCode与equals。
注意:键是常量池中的字符串。

EnumMap
枚举map,要求键为枚举的值。
构造器:public EnumMap(指定枚举class对象)

package ReferenceType;import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;/*** 引用的分类:强、软、弱、虚* 强与弱的引用*/public class Demo01 {public static void main(String[] args) {        //弱引用管理 但是字符串常量不能管理testString();               //弱引用testString2();      //软引用testString3();}public static void testString(){//字符串常量池 共享 不能回收String str = "baby is very good!";//弱引用管理对象WeakReference<String> wr = new WeakReference<String>(str);System.out.println("--弱引用--常量池");System.out.println("gc运行前:"+wr.get());//断开引用str = null; //通知回收System.gc();System.runFinalization();System.out.println("gc运行后:"+wr.get());}public static void testString2(){//弱引用运行垃圾回收机制,都会被回收。String str = new String("coco is very good!");WeakReference<String> wr = new WeakReference<String>(str);System.out.println("--弱引用--");System.out.println("gc运行前:"+wr.get());//断开引用str = null; //通知回收System.gc();System.runFinalization();System.out.println("gc运行后:"+wr.get());}public static void testString3(){String str = new String("baby is very good!");SoftReference<String> wr = new SoftReference<String>(str);System.out.println("--软引用--");System.out.println("gc运行前:"+wr.get());//断开引用str = null;     //通知回收System.gc();System.runFinalization();System.out.println("gc运行后:"+wr.get());}
}

运行结果:

--弱引用--常量池
gc运行前:baby  is  very  good!
gc运行后:baby  is  very  good!
--弱引用--
gc运行前:coco  is  very  good!
gc运行后:null
--软引用--
gc运行前:baby  is  very  good!
gc运行后:baby  is  very  good!
package ReferenceType;import java.util.WeakHashMap;
/*** WeakHashMap 键为弱引用,gc运行立即回收。* @author liguodong**/
public class Demo02 {
    public static void main(String[] args) {WeakHashMap<String,String>  map = new WeakHashMap<String,String>(); //测试数据//常量池对象,不会回收map.put("abc","a");map.put("d","test");//gc运行, 已被回收map.put(new String("coco"), "c");map.put(new String("dfg"), "dx");//通知回收System.gc();System.runFinalization();System.out.println("gc运行后:"+map.size());}
}

运行结果:

gc运行后:2
package ReferenceType;import java.util.IdentityHashMap;
/*** IdentityHashMap 只比较地址 键比较 地址去重* @author liguodong**/
public class Demo03 {
    public static void main(String[] args) {IdentityHashMap<String, String> map = new IdentityHashMap<>();//常量池中的"a" map.put("a", "a1");map.put("a", "a2");System.out.println(map.size());map.put(new String("a"), "a3");map.put(new String("a"), "a4");System.out.println(map.size());}
}

运行结果:

1
3
package ReferenceType;import java.util.EnumMap;/*** Enum要求键为枚举* @author liguodong*/public class Demo04 {
    public static void main(String[] args) {EnumMap<Season, String> map = new EnumMap<>(Season.class);//存放值map.put(Season.SPRINT, "春天");map.put(Season.SUMMER, "夏天");map.put(Season.AUTUMN, "秋天");map.put(Season.WINTER, "冬天");System.out.println("gc运行后:"+map.size());}
}
//季节
enum Season
{SPRINT,SUMMER,AUTUMN,WINTER
}

运行结果:

gc运行后:4

五、同步控制与只读设置
同步控制:多线程并发访问集合的线程安全。
1、常用容器ArrayList、HashMap、HashSet等都是线程不安全的。
2、Collections提供了synchronizedXXX()方法,将指定容器包装成同步
synchronizedCollection
synchronizedList()
synchronizedMap()
synchronizedSet()

不可变设置:只读访问,Collections提供了三种方法
1、emptyXxx() 空的不可变的集合
2、singletonXxx() 一个元素不可变的集合
3、unmodifiableXxx() 不可变容器

package SynchronizedCollection;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;/*** 使用Collections管理同步容器* synchronizedList()* synchronizedSet()* synchronizedMap()*/
@SuppressWarnings("all")
public class Demo01 {
    public static void main(String[] args) {List<String >  list = new ArrayList<String>();list.add("a");list.add("b");//list可以同步List<String> synList = Collections.synchronizedList(list);System.out.println("线程安全的list制定完毕");        }
}
package SynchronizedCollection;import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;/*** 只读设置* emptyXxx() 空的不可变的集合* emptyMap* emptyList* emptySet * singletonXxx() 一个元素的容器 不可变的集合* sington(T o)* singtonList(T o)* singtonMap(K key,V value) * unmodifiableXxx 不可变容器* unmodifiableList(List<? extends T> list) * unmodifiableSet(Set<? extends T> s) * unmodifiableMap(Map<? extends K,? extends V> m)*/
@SuppressWarnings("all")
public class Demo02 {
    private static final int String = 0;public static void main(String[] args) {Map<String,String> map = new HashMap<>();   map.put("test","test");map.put("baby", "baby");//只读控制Map<String, String> map2 = Collections.unmodifiableMap(map);//map2.put("a", "a");//不能操作System.out.println(map2.size());//一个元素的容器List<String> list = Collections.singletonList(new String("fsda"));//list.add("fsaf");//list.add("dsaf");//只能包含一个元素的容器 不被支持System.out.println(list);   Set<String> set = new HashSet<>();set.add("123");System.out.println(set);    set = null;System.out.println(oper(set));}public static Set<String> oper(Set<String> set){if(null==set){return Collections.EMPTY_SET;//外部获取避免NullPointerException}//操作return set;}
}

运行结果:

2
[fsda]
[123]
[]
  相关解决方案