这个可恶的项目忙的不得了,不知道什么时候才能验收,烦人的很。
接着上一篇
线性表
规则集不能存储重复的元素,为了允许在一个集合中存储重复的元素,需要使用线性表。线性表不仅可以存储重复的元素,而且可以只能存储位置。用户可以根据下表来存取元素。List接口扩展了Collection接口,以定义一个允许重复的有序集合。List接口增加了闻之的操作,并且增加了一个能够双向遍历线性表的新列表迭代器。
add(index:int,element: E):bollean | 在制定下标处添加一个新元素 |
addAll(index:int,c:Collection<? extends E>):bollean | 在指定下标处添加c中的所有元素 |
get(index:int)E | 返回列表中指定下标处的元素 |
indexOf(element:E):int |
返回第一个匹配的元素下标 |
lastIndexOf(element:E):int | 返回最后一个匹配的元素下标 |
lsitIterator():ListIterator<E> | 返回这个列表的元素所用的列表迭代器 |
listIterator(startIndex:int):ListIterator<E> | 返回从startIndex开始的元素所用的列表迭代器 |
remove(index:int》:E | 删除指定下标的元素 |
set(index:int,Element:E):E | 设置指定下标处的元素 |
subList(fromIndex:int,toIndex:int):List<E> | 返回从fromIndex到toindex-1 的 子列表 |
这里值得注意的是 listIteratro(0方法返回ListIterator的一个实例,ListIterator接口扩展了Iterator接口,以增加对线性表的双向遍历能力。
add(o:E):void | 添加指定的对象 |
hasPrevious():boolean | 如果向后遍历时这个列表迭代器有更多的元素则返回true |
nextIndex();int | 返回下一个元素的下标 |
previous():E | f返回这个列表迭代器中的前一个元素 |
previousIndex():int | 返回一个元素的下标 |
set(o:E):void | 使用指定的元素替换previous方法或next方法返回的最后一个元素 |
add (element)方法用于将指定元素插入线性表中,如Iterator接口定义的next()方法的返回值非空,该元素立即被插入到next()方法返回的元素之前,而且,如果previous()方法返回值非空,该元素立即被插入到previous()返回的元素之后,如果线性表中之前没有一个元素,那么element 将成为线性表中唯一的一个元素。新元素被插入到隐式光标前:不影响对next 的后续调用,并且对previous 的后续调用会返回此新元素(此调用把调用nextIndex 或previousIndex 所返回的值增加 1)。
因此,使用一下代码 会导致死循环,不论add操作是在前还是在后。
while(listIterator.hasPrevious()){ print(listIterator.previous()); listIterator.add("测试previous插入"); }
set方法用于将next方法或previous方法返回的最后一个元素替换为指定元素。
在Iterator接口中定义的方法hasNext()用于检测迭代器向前遍历时是否还有元素,儿方法hasPrevious()方法用于检测迭代器向后遍历时是否还有元素。
Iterator接口中定义的方法next()返回迭代器中的下一个元素,儿方法previous()返回跌迭器中的前一个元素。返回nextIndex()返回迭代器中下一个元素的下标,而previousIndex()方法会回前一个元素额下标。
从第一篇的图中可以看到,AbstractList类提供了List接口的部分实现,AbstractSequentialList类扩展了AbstratList类,以提供对链表的支持
数组线性表ArrayList 和链表类LinkedList
ArrayList类和LinkedList类都是实现List接口的具体类,ArrayList 使用动态数组存储元素,LinkedList使用链表存储数据元素。从两者的存储元素的方式可以看出,两者适合的情景不同:
如果不需要在在线性表中插入或删除元素,并且希望通过下标随机访问元素,此时可以使用ArrayList类
如果素要在线性表的任意位置插入或者删除元素,那么无疑应该使用LinkedList。
ArrayList() | 创建一个带默认初始容量的空列表 |
ArrayList(c:Collection<? extends E>) | 从现有集合创建一个数组列表 |
ArrayList(initialCapacity:int) | 创建一个指定初始容量的空列表 |
trimToSize | 将整个ArrayList的实例容量缩小的这个列表的当前大小。 |
LinkedList() | 创建一个默认的空列表 |
LinkedList(c:Collection<? extends E>) | 从现有集合中创建一个列表 |
addFirst(o:E):void | 见对象添加到列表的头部 |
addList(o:E):void | 将对象添加到列表的尾部 |
getFirst():E | 返回这个列表的第一个元素 |
getList():E | 返回最后一个元素 |
removeFirst():E | 返回和删除删除列表的第一个元素 |
removeLast():E | 返回和删除列表的最后一个元素 |
下面贴出一段测试代码
import java.lang.*; import java.util.*; import java.io.*; public class TestList { private static final BufferedReader inputStream = new BufferedReader(new InputStreamReader(System.in)); public static void main(String[] args) { List<String> testList = CreateList(); fileElementToList(testList); itreatorElement(testList); if(testList instanceof LinkedList){ testListItreator(testList.listIterator()); } } private static void print(Object o){ System.out.println(o); } private static String getInput() { try{ return inputStream.readLine(); } catch(IOException ex){ ex.printStackTrace(); return null; } } private static List<String> CreateList(){ print("请输入你要测试的线性表类型,A为ArrayList,L 为 LinkedList E 为 退出程序"); String inputStr = getInput(); if(inputStr.equals("E")){ System.exit(0); } if(inputStr.equals("L")){ return new LinkedList<String>(); } else if ( inputStr.equals("A")){ return new ArrayList<String>(); } else { return CreateList(); } } private static List<String> fileElementToList(List<String> list){ print("请输入一个测试字符串,输入 E 结束输入"); String inputStr = getInput(); while(!inputStr.equals("E")){ if(inputStr.isEmpty()) continue; list.add(inputStr); print("请输入一个测试字符串,输入 E 结束输入"); inputStr = getInput(); } return list; } private static void itreatorElement(List<String> list){ for(String s : list){ print(s); } } private static void testListItreator(ListIterator<String> listIterator){ print("测试链表List"); print("测试链表List:向后遍历"); print("========================================"); while(listIterator.hasNext()){ //listIterator.add("测试next插入"); print(listIterator.next()); } // itreatorElement(testList); print("========================================"); print("测试链表List:倒序遍历"); print("========================================"); while(listIterator.hasPrevious()){ print(listIterator.previous()); listIterator.add("测试previous插入"); } //itreatorElement(testList); } }
线性表和集合的静态方法
可以用treeSet在规则集中存储有序的元素,但是线性表不支持有序存数,。然而,集合框架在Collections类中提供了用于对线性表排序的静态方法。Collections类还包含用户线性表的binarySearch/reverse、shuffle、copy和 fill 方法,以及用于集合的max、min、disJoint和f frequency方法。
sort(list:List):void | 对指定的列表排序 |
sort(list:LIst,c:Comparator):void | 使用指定的比较器,对链表排序 |
binarySearch(list:List,key:Object):int | 利用二分查找发搜索列表中的元素 |
binarySearch(list:List,key:Objext,c:Comparator) | 利用比较器排序后,使用二分查找发查找元素 |
reverse(list:List):void | 颠倒指定的列表 |
reverseOrder():Comparator | 返回逆序比较器 |
shuffle(lsit:List):void | 随机打乱指定的列表 |
shuffle(list:List,rmd:Random):void | 根据指定的随机对象打乱列表顺序 |
copy(des:List,src:List):void | 将源列表复制给目标列表 |
nCopys(n:int,o:Objext):List | 返回包含某个对象n个副本的列表 |
fill(list:List,o:Object):void | 用对象填充列表 |
max(c:Collection):Object | 返回集合对象中的最大的对象 |
max(c:Collection,c:Comparator):Object | 使用比较器返回集合中的最大的对象 |
min(c:Collection):Object | 返回集合中的min对象 |
min(c:Cooolection,C:comparator):Object | 使用比较器返回min对象 |
desjoint(c1:Collection,c2:Collection):boolean、 | 如果c1和c2没有公共元素则返回true |
frequency(c:Collection,e:Object);int | 返回集合中指定元素的出现次数 |
规则集和线性表的性能
下面是我的一个i额测试程序 及结果,当然结构跟环境有关但是结论应该没有问题
import java.util.*; public class SetListPerformanceTest { public static void main(String[] args) { Collection<Integer> hashSet = new HashSet<Integer>(); print("HashSet",10000,getTestTime(hashSet,100000)); Collection<Integer> linkedHashSet = new LinkedHashSet<Integer>(); print("LinkedHashSet",10000,getTestTime(linkedHashSet,100000)); Collection<Integer> treeSet = new TreeSet<Integer>(); print("TreeSet",10000,getTestTime(treeSet,100000)); Collection<Integer> arrayList = new ArrayList<Integer>(); print("ArrayList",10000,getTestTime(arrayList,100000)); Collection<Integer> linkedList = new LinkedList<Integer>(); print("LinkedList",10000,getTestTime(linkedList,100000)); } private static void print(Object o){ System.out.println(o); } private static void print(String collectionTypeName, int size,long timeSpan ){ System.out.println( "对包含"+size +"个int 类型元素的 "+collectionTypeName +"进行测试,所用时间为 " + timeSpan+" 毫秒" ); } public static long getTestTime(Collection<Integer> c,int size){ long startTime = System.currentTimeMillis(); List<Integer> list = new ArrayList<Integer>(); for(int i=0; i<size; i++){ list.add(i); } Collections.shuffle(list); //打乱顺序 for(int element:list) c.add(element); Collections.shuffle(list); //打乱 for(int element:list) c.remove(element); long endTime = System.currentTimeMillis(); return endTime - startTime; } }
我想着再有一篇 java 集合这一块应该结束了, 下一个准备是 多线程,或者IO流,都是基础,老鸟略过。