java集合---视图与包装器
来源:互联网 发布:mysql float 转换int 编辑:程序博客网 时间:2024/05/29 18:34
视图—-通过使用视图可以获得其他实现了Collection与Map接口的对象。映射类的keySet就是这样一个实例。初看起来,好像这个方法创建了一个新集,并将映射中的所有键都填进去,然后返回这个集。但是,事实并非如此。取而代之的是:keySet方法返回一个实现了Set接口的类对象,这个类的方法对原映射进行操作。这种集合就是视图。
轻量级集合包装器
Arrays类的静态方法asList将返回一个包装了普通java数组的List包装器,这个方法可以将数组传递给一个期望得到的列表或集合参数中:
package view;import java.util.Arrays;import java.util.Collections;import java.util.List;public class Testview01 { public static void main(String[] args) { String[] str = new String[10]; //这里返回的对象不是一个ArrayList。它是一个视图对象,带有访问底层数组的get和set方法 List<String> list = Arrays.asList(str); list.set(2, "aaa"); System.out.println(list.get(2)); //改变数组大小的所有方法,例如add、remove方法等,都会抛出Unsupported OperationException异常 //list.add("aaa"); System.out.println(list.size()); System.out.println("----------我是分割线----------"); //asList可以接受可变数目的参数 List<String> names = Arrays.asList("aa", "bb", "cc"); System.out.println(names); //names.add("aaaaaa");同样会报错,原因同上 System.out.println(names.size()); System.out.println("----------我是分割线----------"); List<String> set = Collections.nCopies(100, "default"); //实际上在这里只进行了一次赋值操作,详见jdk System.out.println(set.get(0) == set.get(10)); }}
这是关于Collections.nCopies()方法的jdk源码截图,这里充分说明了它只进行了一次赋值。
区分Collections类和Collection接口
Collections类包含了很多实用的方法,这些方法的参数和返回值都是集合;不要与Collection接口混淆。
//这个方法将返回一个视图对象。这个对象实现了Set接口,返回的对象实现了一个不可修改的单元素集, //而不需要付出建立数据结构的开销 Set singleton = Collections.singleton(names); for(Object sets : singleton) { System.out.println(sets);
子范围
package view;import java.util.Arrays;import java.util.List;import java.util.SortedMap;import java.util.SortedSet;import java.util.TreeMap;import java.util.TreeSet;public class TestView02 { public static void main(String[] args) { String[] str = new String[]{"aa", "dd", "ff", "cc", "qq", "bb"}; List<String> list = Arrays.asList(str); System.out.println(list); List group = list.subList(2, 5); System.out.println(group); System.out.println("----------我是分割线----------"); SortedSet<String> set = new TreeSet<String>(list); SortedSet<String> subset = set.subSet("aa", "dd");//大于aa小于dd不包含dd System.out.println(subset); subset.clear();//删除选中的项,并且直接反应在原映射中 System.out.println(set); System.out.println("----------我是分割线----------"); SortedMap<Integer, String> map = new TreeMap<Integer, String>(); map.put(1, "ff"); map.put(2, "aa"); map.put(3, "gg"); map.put(4, "ee"); map.put(5, "cc"); System.out.println(map); SortedMap<Integer, String> submap = map.subMap(2, 4); System.out.println(submap); submap.clear(); System.out.println(map); }}
不可修改视图
Collections 还有几个方法, 用于产生集合的不可修改视图。 这些视图对现有集合增加了一个运行时的检查。 如果发现试图对集合进行修改, 就抛出一个异常, 同时这个集合将保持未修改状态;(再次提醒:注意区分 Collection 和 Collections)
可以使用下列8种方法获得不可修改视图:
Collections.unmodifiableCollection
Collections.unmodifiableList
Collections.unmodifiableSet
Collections.unmodifiableSortedSet
Collections.unmodifiableMap
Collections.unmodifiableSortedMap
Collections.unmodifiableNavigableSet
Collections.unmodifianleNavigableMap
每个方法都定义于一个接口。如, Collections.unmodifiableList 与 ArrayList、LinkedList 或者任何实现了 List接口的其他类一起协同工作;
package view;import java.util.Collections;import java.util.LinkedList;import java.util.List;public class TestView03 { public static void main(String[] args) { List<String> list = Collections.nCopies(5, "default"); List view = Collections.unmodifiableList(list);//该方法获取不可修改的视图 System.out.println(view.get(0)); view.add("aaa");//报错,获取的是不可修改视图 System.out.println("----------我是分割线----------"); List<String> staff = new LinkedList<String>(); lookAt(Collections.unmodifiableList(staff)); }}
Collections.unmodifiableList 方法返回一个实现List接口的类对象。当然,lookAt方法 可以调用 List 接口中的所有方法, 而不只是访问器。但是所有的更改器方法,已经被重新定义为 抛出一个 UnsuportedOperationException 异常,而不是 将调用传递给底层集合;
注意:
不可修改视图并不是聚合本身不可修改,只是无法通过其投影出来的视图修改原集合。仍然可以实用集合的原始引用修改原集合。
由于视图只是包装了接口而不是实际的集合对象,所以只能访问接口中定义的方法。例如,LinkedList类有一些常用的方法,addFirst和addLast,他们都不是List接口方法,不能通过不可修改视图访问。
同步视图
如果由多个线程访问集合,就必须确保集不会被意外的破坏。类库设计者使用视图机制来确保常规集合的线程安全,而不是实现线程安全的集合。例如,Collections类的静态synchronizedMap可以将任何一个映射表转换成具有同步访问方法的Map:
Map<String, Employee> map = Collections.synchronizedMap(new HashMap<String, Employee>())
受查视图
package view;import java.util.ArrayList;import java.util.Collections;import java.util.Date;import java.util.List;public class TestView04 { public static void main(String[] args) { ArrayList<String> str = new ArrayList<String>(); ArrayList string = str; string.add(new Date());//到这里并没有发现添加的类型不符 Date date = (Date)string.get(0); System.out.println(date); /*String s = (String) string.get(0);//这里检测到类型不匹配 System.out.println(s);*/ System.out.println("----------我是分割线----------"); ArrayList<String> str2 = new ArrayList<String>(); List<String> safe = Collections.checkedList(str2, String.class); List string02 = safe; string02.add(new Date());//编译器没有检测到这里的add异常 System.out.println("ok"); }}
- java集合---视图与包装器
- 集合---视图与包装器
- java集合——视图与包装器
- java集合框架(三)-视图与包装器
- 集合中视图与包装器概念,及Arrays.asList不可修改的原理解释
- java集合框架系列---包装器
- Java集合框架官方教程(5):集合类的同步包装器/不可变包装器
- 9.4 视图和包装器
- Java对象包装器与自动打包
- java同步包装器与线程安全
- 【java】-- 调戏Integer 包装与解包装
- 包装类 与 简单集合框架
- Java字符串与包装类
- Java 包装器潜规则
- java包装器详解
- java包装器
- Java数据类型包装器
- Java 原生类型与包装器类型深度剖析
- ML-朴素贝叶斯
- Java记录 -69- Comparable与Comparator的区别
- Java记录 -70- HashSet源码剖析
- Java记录 -71- HashMap源码剖析
- Java知识链整理
- java集合---视图与包装器
- 知识链-源码分析
- 知识链-Java集合
- php不用eval实现字符串转数组
- 知识链-Java多线程并发
- 知识链-Java内存管理
- 知识链-设计模式
- 知识链-算法
- 知识链-数据结构