Java容器(集合),持有对象总结

xiaoxiao2021-02-28  112

基本概念

如下图: 为解决数组固定尺寸的限制,java类库提供容器类来解决这问题。其中包括List,Set,Map,Queue,也称集合类。编程时可以将任意数量的对象置于容器,不用在意容器大小。 容器类库可以划分为:

Collection:独立的序列,元素服从一条或多条规则。其中List按照插入的顺序保持元素,Set不能有重复元素,Queue按照排队规则确定对象产生的顺序。Map:一组成对的键值对对象,允许用键查找,ArrayList允许用数字查找值。

向Collection添加一组元素

java.util包中的Arrays和Collections类的Arrays.asList()方法和Collections.addAll()方法可以在Collection对象中添加一组元素。

Arrays.asList()接受一个数组或是逗号分隔的元素列表,将其妆化为List对象;Collections.addALl()接受一个Collection对象,以及一个数组或者逗号分隔的元素列表,将元素添加到Collection中;Collection.addAll()运行快,只能接受Collection对象作为参数,所以不如前两者灵活。

如下:

public class addGroups(){ public static void main(String[] args){ Conllection<Integer> conllection = new ArrayList<Integer>(Arrays.asList(1,2,3)); Integer[] moreInts = {4,5,6}; collection.addAll(Arrays.asList(moreInts)); Collections.addAlls(conllection, 7,8,9); Collections.addAlls(conllection, moreInts); } }

可以直接使用Arrays.asList()的输出,将其作为List,此时,底层表示为数组,无法调整尺寸,若用add(),delete()添加或删除元素,会引发改变数组尺寸,产生错误。

List<Integer> list = Arrays.asList(10,11,12); list.set(1,99); //可以修改元素值 list.add(13); //产生错误,尝试改变数组尺寸

List

List可以将元素维护在特定的序列中,有两种类型List:

ArrayList:随机访问元素快速,在List中插入和移除元素比较慢LinkedList:通过代价较低的在List中进行插入删除,提供了优化的顺序访问,LinkedList在随机访问方面比较慢,但特性集比ArrayList更大。

具体方法操作如下例所示:

import java.util.*; import static java.lang.System.out; public class Main { public static void main(String[] args) { List<String> list = new ArrayList<String>(Arrays.asList("red","blue","white","grey")); //add(int index,String value)向List中添加插入元素 list.add("yellow"); out.println(list); //contains(String value)判断List中是否包含该元素 out.println(list.contains("yellow")); //indexOf(String value)查询元素的位置 out.println(list.indexOf("blue")); //remove(String value)删除元素 out.println(list.remove("blue")); out.println(list); //subList(int index,int _index)截取片断,返回一个新的List对象 List<String> _list = list.subList(1,4); out.println(_list); //containAll(List object)判断一个List中是否包含另一个List中的所有值 out.println(list.containsAll(_list)); //Collections.sort(List object)对List进行排序 Collections.sort(_list); out.println(_list); List<String> copy_list = new ArrayList<>(list); _list = Arrays.asList(list.get(1),list.get(3)); out.println(_list); out.println(copy_list); //retainAll()取交集 copy_list.retainAll(_list); out.println(copy_list); //removeALl()从List中移除参数List中所有元素 copy_list.removeAll(_list); out.println(copy_list); //set()设值,在指定索引处,替换位置上的元素 list.set(1,"green"); out.println(list); //addAll()在List中插入新的列表 list.addAll(1,_list); out.println(list); //isEmpty()判断List是否为空 out.println(list.isEmpty()); //clear()清除所有元素 list.clear(); out.println(list); //toArray()将Collection转换为一个数组,为重载方法,无参版本返回的是Object数组 Object[] array = _list.toArray(); out.println(array[0]); } }

Iterator

迭代器(设计模式)是一个对象,用来遍历并选择序列中的对象,通常被称为轻量级对象,创建代价小。Java的Iterator只能单向移动。

iterator()要求容器返回一个Iterator;使用next()获得序列中下一个元素;使用hasNext()检查序列中是否还有元素;remove()将迭代器返回的元素删除;

如下示例:

import java.util.*; import static java.lang.System.out; public class Main { public static void main(String[] args) { List<String> list = new ArrayList<String>(Arrays.asList("red","blue","white","grey")); Iterator<String> iter = list.iterator(); while(iter.hasNext()){ String s = iter.next(); out.println(s); } for(String _s : list) out.println(_s); iter = list.iterator(); for(int i = 0;i < 2;i++){ iter.next(); iter.remove(); } out.println(list); } }

若是所创建的List能把相同的代码应用于Set,将显得很方便,代码重组显然不适合,所以我们使用迭代器。创建一个display()方法:

import java.util.*; import static java.lang.System.out; public class Main { public static void display(Iterator<String> iter){ while(iter.hasNext()){ String s = iter.next(); out.println(s); } } public static void main(String[] args) { List<String> list = new ArrayList<String>(Arrays.asList("red", "blue", "white", "grey")); LinkedList<String> L_list = new LinkedList<String>(list); HashSet<String> H_list = new HashSet<String>(list); TreeSet<String> T_list = new TreeSet<String>(list); display(list.iterator()); display(L_list.iterator()); display(H_list.iterator()); display(T_list.iterator()); } }

ListIterator

ListIterator是Iterator的子类型,用于LIst的访问。Iterator只能单向移动,但是ListIterator可以双向移动。 其中的previousIndex()和nextIndex()可以获取到当前位置的前一个和后一个元素索引,hasPrevious()判断一个元素是否存在,set()用于替换元素。

import java.util.*; import static java.lang.System.out; public class Main { public static void main(String[] args) { List<String> list = new ArrayList<String>(Arrays.asList("red", "blue", "white", "grey")); ListIterator<String> iter = list.listIterator(); while(iter.hasNext()){ System.out.print(iter.next()+","+iter.nextIndex()+","+iter.previousIndex()+" "); } System.out.println(); while(iter.hasPrevious()) out.print(iter.previous()+" "); out.println(); iter = list.listIterator(2); while(iter.hasNext()){ iter.next(); iter.set("girl"); } out.println(list); } }

LinkedList

LinkedList随机访问比ArrayList逊色,但是元素的插入删除比ArrayList迅速的多。LinkedList添加了栈,队列,双端队列的方法。

getFirst(),element():返回列表的头元素,而不是移除,若列表为空,则抛出NoSunchElementException;peek():同上,只是列表为空时,返回null;removeFirst(),remove():移除并返回列表的头,列表为空抛出NoSunchElementException;poll():同上,只是列表为空返回null;addFirst(),add(),addLast():将某个元素插入到列表的(端)尾部;removeLast():移除并返回列表最后一个元素;

如下:

import java.util.*; import static java.lang.System.out; public class Main { public static void main(String[] args) { LinkedList<String> list = new LinkedList<String>(Arrays.asList("red","blue","green","yellow")); out.println(list); out.println("getFirst():"+list.getFirst()); out.println("element():"+list.element()); out.println("peek():"+list.peek()); out.println("remove():"+list.remove()); out.println("removeFirst():"+list.removeFirst()); out.println("poll():"+list.poll()); list.addFirst("red"); list.addLast("blue"); out.println(list); out.println("removeLast():"+list.removeLast()); } } [red, blue, green, yellow] getFirst():red element():red peek():red remove():red removeFirst():blue poll():green [red, yellow, blue] removeLast():blue

Stack

“栈”称为“先进后出”(LIFO)容器。有时也称作叠加栈。最后压入的元素,最后一个弹出。LinkedList可以实现Java中的栈。 使用LInkedList定义一个Stack类:

import java.util.LinkedList; public class Stack<T>{ private LinkedList<T> Storage = new LinkedList<T>(); public void push(T v) { storage.addFirst(v); } public T peek(){ return storage.getFirst(); } public T pop(){ return storage.removeFirst(); } public boolean empty(){ return storage.isEmpty(); } public String toString(){ return storage.toString(); } }

Set

Set不保存重复元素,常用作测试归属性可以很容易判断对象是否在Set中,加快了对快速查询的优化。 Set有着与Collection完全一样的接口,没有任何额外功能,只是行为不同而已。如下为Set示例:

import java.util.*; import static java.lang.System.out; public class Main { public static void main(String[] args) { Random rand = new Random(47); //Set<Integer> set = new HashSet<Integer>(); //Set<Integer> set = new TreeSet<Integer>(); Set<Integer> set = new LinkedHashSet<Integer>(); for(int i = 0;i<1000;i++){ set.add(rand.nextInt(30)); } out.println(set); } }

运行结果:

HashSet: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29] TreeSet: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29] LinkedHashSet [8, 5, 13, 11, 1, 29, 28, 20, 12, 7, 18, 21, 19, 16, 0, 14, 3, 26, 25, 10, 2, 24, 4, 6, 22, 27, 17, 9, 23, 15]

由运行结果可知,HashSet和TreeSet按顺序输出,以往的HashSet使用的是散列,现在或许已经改变了元素存储方式,TreeSet存储在红黑树中,LinkedHashSet使用了散列存储,看起来更是使用了链表维护元素插入顺序。

contains()和containsAll(Set对象)用来检查元素的归属remove()和removeAll(Set对象)用来删除元素

若是想要列出一个文件上所有的单词时,可以使用net.mindview.TextFile工具,并将其写入Set中。

new TextFile("Exzample.hava", "\\W+");

其中“\W+”表示正则表达式“一个或多个字母”。

Queue

队列是“先进先出”容器,容器一段放入元素,另一端取出。LinkedList支持队列的行为,实现了Queue接口,可以通过LinkedList向上转型为Queue。

Queue<String> queue = new LinkedList<String>();

其中Queue的offer()方法可以将一个元素插入到队尾,或返回false。peek()和element()在不移除的情况返回队头。poll()和remove()移除并返回队头。

Map

Map是一种将对象与对象相关联的设计,HashMap设计用来快速访问,而TreeMap保持“键”始终处于排序状态,所以没有HashMap快,LInkedHashMap保持元素插入的顺序,但也通过散列提供快速访问的能力。 Map可以将对象映射到其他对象。例如,对Random产生的数字进行计数,键位Random产生的数字,值是数字出现的次数。

import java.util.*; import static java.lang.System.out; public class Main { public static void main(String[] args) { Random rand = new Random(47); Map<Integer, Integer> map = new HashMap<Integer, Integer>(); for(int i =0; i<1000;i++){ int r= rand.nextInt(30); Integer num = map.get(r); map.put(r, num==null?1:num+1); } out.println(map); } }

此外,可以通过containsKey()和containsValue()测试一个Map,判断是否包含某个键或某个值。

import java.util.*; import static java.lang.System.out; public class Main { public static void main(String[] args) { Map<Integer, String> map = new HashMap<Integer, String>(); map.put(0, "red"); map.put(1, "blue"); map.put(2, "yellow"); out.println(map); out.println(map.containsKey(1)); out.println(map.containsValue("blue")); } }
转载请注明原文地址: https://www.6miu.com/read-54818.html

最新回复(0)