Java基础:集合,了解一下
一、引用分类
- 强引用:StrongReference gc,引用指向对象,运行不回收
- 软引用:SoftReference gc,运行时可能回收(jvm内存不够)
- 弱引用:WeakReference gc,运行时立即回收(字符串常量池不能回收)
public static void main(String[] args) {
//字符串常量池是共享的,不能回收
String str = "hello java";
//弱引用,管理对象
WeakReference<String> wr = new WeakReference<>(str);
System.out.println("运行前:"+wr.get());
//断开引用
str = null;
//通知回收
System.gc();
System.runFinalization();
System.out.println("运行后:"+wr.get());
}
public static void main(String[] args) {
//此时就不是字符串常量了,会被回收
String str = new String("hello java");
//弱引用,管理对象
WeakReference<String> wr = new WeakReference<>(str);
System.out.println("运行前:"+wr.get());
//断开引用
str = null;
//通知回收
System.gc();
System.runFinalization();
System.out.println("运行后:"+wr.get());
}
- 虚引用:PhantomReference gc,相当于无引用,主要跟踪对象被回收的状态,不能单独使用,必须与引用队列联合使用。
GC:garbage collection,垃圾回收器,调用此方法意味着 Java 虚拟机做了一些努力来回收未用对象,以便能够快速地重用这些对象当前占用的内存。当控制从方法调用中返回时,虚拟机已经尽最大努力回收了所有丢弃的对象。
二、三个Map接口的实现类
- WeakHashMap:建为弱引用,回收键后自动删除key-value对象。
public static void main(String[] args) {
//建为弱引用,回收键后自动删除key-value对象
WeakHashMap<String,String> wMap = new WeakHashMap<>();
//测试数据
//常量池对象,不会回收
wMap.put("a", "one");
wMap.put("b", "two");
//gc运行就会被回收
wMap.put(new String("c"), "three");
wMap.put(new String("d"), "four");
//通知回收
System.gc();
System.runFinalization();
System.out.println(wMap.size());
}
- IdentityHashMap:
- 键只以地址去重,而不是比较hashcode与equals;
- 键是常量池中的字符串。
public static void main(String[] args) {
//键只以地址去重
IdentityHashMap<String,String> iMap = new IdentityHashMap<>();
iMap.put("hello", "java");
iMap.put("hello", "world");
iMap.put(new String("hello"), "hadoop");
System.out.println(iMap.get("hello"));
System.out.println(iMap.size());
}
- EnumMap:
- 键必须是枚举的值(枚举enum:常量的集合);
- 构造器:public EnumMap(指定枚举class对象)
public static void main(String[] args) {
//构造器:public EnumMap(指定枚举class对象)
EnumMap<Season,String> eMap = new EnumMap(Season.class);
//键必须是枚举的值(枚举enum:常量的集合)
eMap.put(Season.Spring, "春天");
eMap.put(Season.Summer, "夏天");
eMap.put(Season.Autumn, "秋天");
eMap.put(Season.Winter, "冬天");
System.out.println(eMap.size());
}
enum Season{
Spring,Summer,Autumn,Winter;
}
三、同步控制
多线程并发访问集合的线程安全
- 常用容器ArrayList、HashSet、HashMap等都是线程不安全的
- Collections提供了synchronizedXxx()方法,将指定容器包装成同步
- synchronizedList()
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("dog");
list.add("pig");
//list可以同步
List<String> synList = Collections.synchronizedList(list);
System.out.println("线程安全的list制作完毕"+synList);
}
- synchronizedSet()
- synchronizedMap()
四、只读设置(不可变设置)
“只读”访问,Collections提供了三种方法
- emptyXxx() 空的不可变的集合
public static void main(String[] args) {
Set<String> set = new HashSet<>();
System.out.println(oper(set));
}
public static Set<String> oper(Set<String> set){
if (null == set){
return Collections.emptySet();
}
return set;
}
- SingletonXxx() 一个元素不可变的集合
public static void main(String[] args) {
List<String> list = Collections.singletonList(new String());
list.add("公孙离");
//list.add("黄忠");
/**
* 该容器只能包含一个元素
* Exception in thread "main" java.lang.UnsupportedOperationException
* at java.util.AbstractList.add(AbstractList.java:148)
* at java.util.AbstractList.add(AbstractList.java:108)
* at com.hxy.set.ListDemo.main(ListDemo.java:9)
*/
System.out.println(list.size());
}
- unmodifiableXxx() 不可变容器
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
map.put("张飞", "男");
map.put("貂蝉", "女");
map.put("吕布", "男");
//只读控制,不可变容器
Map<String, String> map1 = Collections.unmodifiableMap(map);
//map1.put("关羽", "男");
/**
* Exception in thread "main" java.lang.UnsupportedOperationException
* at java.util.Collections$UnmodifiableMap.put(Collections.java:1457)
* at com.hxy.set.Demo.main(Demo.java:14)
*/
System.out.println(map1.size());
}