java基础学习(十)容器-1
来源:互联网 发布:php中sleep函数 编辑:程序博客网 时间:2024/05/29 18:58
java容器类库的用途是保存对象,它提供两种不同的类型:
1、Collection。独立元素的序列。子类List必须按照插入的顺序保存元素;Set不能有重复的元素。
2、Map。一组成对的键值对对象。
在创建具体类的对象时,将其转型为对应的接口,然后在其余的代码中都使用这个接口,例如:
List<String> strList=new ArrayList<>();List<String> strList2=new LinkedList<>();
但是LinkList具有在List中未包含的额外方法,如果想使用这些额外方法,那就不能将它们向上转型为更通用的接口。
实例,在Collection中填充Integer对象:
public static void main(String[] args) { //继承自Collection的类的对象都可以使用 Collection<Integer> c=new ArrayList<Integer>(); for(int i=0;i<10;i++){ //在使用任何种类的List,不关心是否存在重复元素 //而在Set中,只有元素不存在才会被添加 c.add(i); } //遍历容器 for(Integer i:c){ System.out.println(i); } }
利用Arrays和Collection类中的实用方法,添加一组元素:
public static void main(String[] args) { //Arrays.asList()方法可以接受一个数组或者一个逗号分隔的元素列表(可变参数,元素个数不固定) Collection<Integer> collection=new ArrayList<Integer>(Arrays.asList(1,2,3)); Integer[] moreInt=new Integer[]{5,6,7}; //利用addAll()添加元素,只能接受另一个Collection类型 collection.addAll(Arrays.asList(moreInt)); for(Integer i:collection){ System.out.print(i+" "); } //注意,上面的collection只能接受Collection对象,这样不灵活 //可以使用Collections.addAll()方法,可以接受Collection对象, //以及使用一个数组 或者 用逗号分隔的元素列表(可变参数) //但是不能三者都放在一起,且必须有一个Collection对象,因为要将元素填充到collection中 Collections.addAll(collection,9,8); Collections.addAll(collection,moreInt); System.out.println(); for(Integer j:collection){ System.out.print(j+" "); } }//结果:1 2 3 5 6 7 1 2 3 5 6 7 9 8 5 6 7
当直接使用Arrays.asList()的输出,将其作为一个List,其底层表示的是数组,不能改变数组大小。
public static void main(String[] args) { List<Integer> intList= Arrays.asList(3,2,4); //增加或删除元素,会导致出现异常:UnsupportedOperationException //intList.add(6); //intList.add(4,6); //intList.remove(0); for(Integer i:intList){ System.out.println(i+" "); } }
Arrays.asList()方法会根据元素的实际类型产生正确的List类型:
public class AsListInference { public static void main(String[] args) { List<Snow> sonw= Arrays.asList(new Power(),new Crusty(),new Slush()); //不能编译通过 //List<Snow> snows_1=Arrays.asList(new Light(),new Heavy()); //混合情况也不能编译 //List<Snow> snow_2=Arrays.asList(new Power(),new Light()); //正确的方法,创建一个空的collection对象,在进行填充 List<Snow> snows_3=new ArrayList<Snow>(); Collections.addAll(snows_3,new Light(),new Heavy()); //也可以使用显式类型参数说明,告诉编译器List的实际类型, List<Snow> snows_4=Arrays.<Snow>asList(new Light(),new Heavy()); }}class Snow{}class Power extends Snow{}class Light extends Power{}class Heavy extends Power{}class Crusty extends Snow{}class Slush extends Snow{}
打印数组中的元素可以使用Array.toString()方法,但是容器可以直接打印:
public class PrintContain { static Collection fill(Collection<String> collection){ collection.add("rat"); collection.add("cat"); collection.add("dog"); collection.add("dog"); return collection; } public static void main(String[] args) { //打印数组 String[] str=new String[]{"rat","cat","dog","dog"}; System.out.println(Arrays.toString(str)); //打印容器 System.out.println(fill(new ArrayList<String>())); System.out.println(fill(new LinkedList<String>())); System.out.println(fill(new HashSet<String>())); System.out.println(fill(new TreeSet<String>())); System.out.println(fill(new LinkedHashSet<String>())); }}//结果//打印数组[rat, cat, dog, dog]//List类型按照插入的顺序保存元素[rat, cat, dog, dog][rat, cat, dog, dog]//Set类型,每个相同的项保存一次//HashSet能最快获取元素,存储顺序无意义[rat, cat, dog]//TreeSet按照比较结果升序保存对象[cat, dog, rat]//LinkedHashSet按照被添加的顺序保存对象[rat, cat, dog]
List容器
List可以将元素维护在特定的序列中,可以在List的中间插入和移除元素。
两种类型的List:
1、ArrayList:擅长随机访问元素,但在其中插入和移除元素时较慢
2、LinkedList:方便在List中间进行插入和删除操作,在随机访问方面比较慢。
迭代器
迭代器是一个轻量级对象,主要是遍历并选择序列中的对象,而不必关系该序列底层的结构。Java中的Iterator只能单向移动(也就是只能next,向前移动)。
public static void main(String[] args) { List<String> strList=new ArrayList<String>(); Collections.addAll(strList,"dog","cat","mouse","rate"); //不必关心容器的确切类型 //方法iterator()返回一个Iterator,将返回序列的第一个元素 Iterator<String> iterator=strList.iterator(); //hasNext()检查序列中是否还有元素 while(iterator.hasNext()){ //获取序列中的下一个元素 String str=iterator.next(); System.out.print(str+" "); } System.out.println(); //因为iterator已经到最后没有元素了,需要重新建立对象 iterator=strList.iterator(); for(int i=0;i<2;i++){ //将新近返回的元素删除 iterator.next(); iterator.remove(); } System.out.print(strList); }结果:dog cat mouse rate [mouse, rate]
ListIterator
它是Iterator的子类型,只能用于各种List类的访问。并且可以双向移动。
public static void main(String[] args) { List<String> petList=new ArrayList<String>(); Collections.addAll(petList,"dog","cat","pig","rate"); ListIterator<String> li=petList.listIterator(); while (li.hasNext()){ //返回迭代器在列表中指向的当前位置的前一个和后一个元素的索引 String ne= li.next(); int next= li.nextIndex(); int pre= li.previousIndex(); System.out.print(ne+" "+next+" "+pre+" "); } System.out.println(); //也可以反向移动 while (li.hasPrevious()){ String previous= li.previous(); System.out.print(previous+" "); } System.out.println(); //可以一开始就指向列表索引为2的元素处的ListIterator li=petList.listIterator(2); while (li.hasNext()){ System.out.print(li.next()+" "); } }//结果:dog 1 0 cat 2 1 pig 3 2 rate 4 3 rate pig cat dog pig rate
LinkedList
在List中插入和移除操作的效率比ArrayList更高效。但在随机访问方面要逊色一些。
public static void main(String[] args) { List<String> link=new LinkedList<String>(); Collections.addAll(link,"dog","rat","mutt","pugl"); System.out.println("link="+link); //返回列表的第一个元素 //list中没有addFirst()方法 System.out.println("link.get()="+link.get(0)); //移除并返回元素 System.out.println("link.remove()="+link.remove(1)); }//结果link=[dog, rat, mutt, pugl]link.get()=doglink.remove()=rat
Stack
栈指后进先出的容器,最后压入栈的元素,最后弹出栈。
LinkedList能够直接实现栈的所有功能的方法,因此可以直接将LinkedList作为栈使用。
public class StackTest<T> { //Stack是用LinkedList实现的 private LinkedList<T> storge=new LinkedList<T>(); //插入一个元素 public void push(T t){storge.addFirst(t);} //返回栈顶元素,但是并不移除 public T peek(){return storge.getFirst();} //返回并移除栈顶元素 public T pop(){return storge.removeFirst();} //判断栈是否为空 public boolean empty(){return storge.isEmpty();} }
Set
set不保存重复对象。
存储方式的不同:HashSet使用的散列函数,输出的元素没有规律。
TreeSet将元素存储在红-黑树数据结构,对结果进行排序。
LinkedHashSet也使用散列函数,但是使用了链表来维护元素的插入顺序。
HashSet 和TreeSet
public static void main(String[] args) { Random random=new Random(100); Set<Integer> intset=new HashSet<Integer>(); Set<Integer> treeSet=new TreeSet<Integer>(); Collections.addAll(intset,21,32,4,6,1); Collections.addAll(treeSet,21,32,4,6,1); Iterator<Integer> it=intset.iterator(); while(it.hasNext()){ //遍历HashSet,输出的顺序没有规律可循 System.out.print(it.next()+" "); } System.out.println(); Iterator<Integer> itTree=treeSet.iterator(); while(itTree.hasNext()){ //遍历TreeSet,对结果进行排序 System.out.print(itTree.next()+" "); } } //结果 32 1 4 21 6 1 4 6 21 32
Map
public static void main(String[] args) { Map<String,String> petMap=new HashMap<String, String>(); petMap.put("my Cat","Molly"); petMap.put("my dog","ginger"); petMap.put("MY Mamster","Bosco"); //map中包含某个键或值 petMap.containsKey("my dog"); petMap.containsValue("my Cat"); //遍历map //keySet返回键的Set for(String my:petMap.keySet()){ System.out.println("主人:"+my+"宠物:"+petMap.get(my)); } //values返回值的collection Iterator<String> valIte=petMap.values().iterator(); while(valIte.hasNext()){ System.out.println(valIte.next()); } }
Queue
队列是典型的先进先出的容器。从容器的一端放入事物,从另一端取出,并且事物放入容器的顺序与取出的顺序是相同的。队列可以安全的将对象从一个任务传输给另一个任务。
LinkedList实现了Queue接口,可以把它作为一种实现。
public static void main(String[] args) { Queue<Integer> queue=new LinkedList<Integer>(); Random random=new Random(47); //offer方法将一个元素插入到队尾,返回true System.out.println(queue.offer(444)); for(int i=0;i<10;i++){ queue.offer(random.nextInt(i+10)); } System.out.println(queue); }
Collection和Iterator
Collection是描述所有序列容器的共性的根接口,它会被认为是一个附属接口,为了表示其他接口的共性而出现的接口。AbstractCollection提供Collection的默认实现,在穿件AbstractCollection的子类型时,而其中没有不必要的代码的重复。
迭代器和容器都可以用在Map或Collection的子类型来工作。
//使用迭代器 public static void display(Iterator<String> it){ while (it.hasNext()){ System.out.print(it.next()+" "); } } //使用容器 public static void display(Collection<String> c){ for(String str:c){ System.out.println(str+" "); } } public static void main(String[] args) { List<String> strList=new ArrayList<String>(); Set<String> strSet=new HashSet<String>(); Collections.addAll(strList,"dog","pig","cat"); Collections.addAll(strSet,"first","second","third"); Map<String,String> strMap=new LinkedHashMap<String, String>(); strMap.put("zhangsan","lisi"); strMap.put("wangwu","zhaoliu"); //使用迭代器 display(strList.iterator()); display(strSet.iterator()); display(strMap.keySet().iterator()); //使用容器 display(strList); display(strSet); display(strMap.values()); }
当要实现一个不是Collection的外部类时,让其实现该接口会非常困难,即使通过继承AbstractCollection而很容易实现,但是还是需要强制实现iterator()和size()方法。此时使用迭代器比较方便。
Foreach与迭代器
foreach语法主要用于数组,但是也可以应用于任何Collection对象。所有的Collection类(不包括各种Map)都是Iterable类型,数组也不是Iterable类型。Iterable接口包含一个能够产生Iterator的iterator()方法。并且Iterable接口被foreach用来在序列中移动。
任何实现了Iterable的类,都可以将它应用于foreach中。
public static void main(String[] args) { Map<String,String> strMap=new HashMap<String, String>(); strMap.put("one","zhangsan"); strMap.put("two","lisi"); strMap.put("three","wangwu"); for(Map.Entry entry:strMap.entrySet()){ System.out.println(entry.getKey()+":"+entry.getValue()); } }//结果one:zhangsantwo:lisithree:wangwu
- java基础学习(十)容器-1
- Java基础学习笔记(四)容器
- java基础学习(12)容器-2
- Java基础--容器(1)
- Java基础(十)
- 黑马程序员--Java基础学习十(Java线程)
- Java容器(十):subList的陷阱
- java基础学习笔记之十--反射(1)
- 零基础小白JAVA学习笔记(十)
- java学习基础篇(十)单例设计模式
- Java基础学习笔记:(十)static关键字
- java学习基础 Collection容器的区别
- java基础学习之持有对象(容器)
- Java学习--基础类和容器
- XML学习基础(十)
- JS基础学习(十)
- JAVA基础学习(十)--异常、包
- No_16_0324 Java基础学习第二十三天
- 稀疏矩阵的压缩储存,稀疏矩阵的普通转置,稀疏矩阵的快速转置
- bp神经网络的python实现
- EXT CheckboxSelectionModel 多选效果以及获取选定值
- 密码
- 论go语言中goroutine的使用
- java基础学习(十)容器-1
- 熄灯之后的学习——再读《MySQL必知必会》(4)|| 排序数据
- Struts2-Action-8-系列问题(包含模块配置文件、defaultAction)
- SAP SMP iOS kapsel打包注意事项
- 使用stm32主从门控模式精确控制脉冲个数
- 蓝桥杯 圆的面积 java
- PAT-A-1070. Mooncake (25)
- rabbitmq的命令和Web UI管理消息服务器
- 1002. A+B for Polynomials (25)