首页 / JAVA / java基础——集合
java基础——集合
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java基础——集合,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含13743字,纯文字阅读大概需要20分钟。
内容图文
集合与数组的区别:
1.数组是固定长度的;集合的长度是可变的。
2.数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型。
3.数组存储元素必须是同一个数据类型;集合存储的对象可以是不同数据类型。
java集合主要有3种重要的类型:
●List:是一个有序集合,可以存放重复的数据。
●Set: 是一个无序集合,不允许存放重复的数据。
●Map: 是一个无序集合,集合中包含一个键对象和一个值对象, 键对象不允许重复,值对象可以重复。
下面是集合继承结构图-Collection部分,从图中可以很清楚的知道Collection接口下的子接口与实现类的关系。
Collection集合的常用方法:
boolean add(Object o): 向集合中添加元素
boolean addAll(Collection c):把集合c中的元素添加到指定的集合中
void clear():清空集合
boolean isEmpty(): 判断集合中是否有元素
Iterator iterator(): 获取集合所依赖的迭代器对象
boolean contains(Object o): 判断集合中是否包含某个元素
boolean remove(Object o): 删除集合中某个元素
int size(): 获取集合中元素的个数
Object[] toArray(): 将集合转换成数组
1 import java.util.*; 2 3publicclass CollectionDemo { 4publicstaticvoid main(String[] args) { 5 6// 创建集合 7 Collection c = new ArrayList();// 多态 8 9// 添加元素10 c.add(100); // 自动装箱11 c.add("Java编程"); 1213 Person p = new Person("Bill", 21); 14 c.add(p);// Collection集合只能单个存储元素,并且只能存储引用类型 1516// 获取元素个数17 System.out.println(c.isEmpty());// false 说明集合c不为空18 System.out.println("c集合的元素个数为:" + c.size());// 个数为3 1920// 将集合转换成Object类型的数组21 Object[] obj = c.toArray(); 22for (int i = 0; i < obj.length; i++) { 2324// 输出结果:100 Java编程 Person[name=Bill,age=21]25 System.out.println(obj[i]); 26 } 2728// 删除指定元素29 c.remove(100); // 元素100已删30 System.out.println("c集合的元素个数为:" + c.size());// 个数为2 3132// 清空33 c.clear(); 34 System.out.println(c.isEmpty());// true 说明集合c为空35 System.out.println("c集合的元素个数为:" + c.size());// 个数为03637 } 38} 3940class Person { 41 String name; 42int age; 4344 Person(String name, int age) { 45this.name = name; 46this.age = age; 47 } 4849// 重写Object中的toString方法50public String toString() { 51return "Person[name=" + name + ",age=" + age + "]"; 52 } 5354 }
Iterator iterator();获取集合所依赖的迭代器对象
通过迭代器中的方法完成集合的迭代(遍历)
这种方式是所有集合通用的遍历方式
Itertor接口定义的三个方法:
boolean hasNext():如果仍有元素可以迭代,则返回 true。
Object next(): 返回迭代的下一个元素。
void remove(): 从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。
Iterator必须依附于Collection对象,若有一个Iterator对象,则必然有一个与之关联的Collection对象。
当使用Iterator对集合元素进行迭代时,Iterator并不是把集合元素本身传给迭代变量,而是把集合元素的值传给迭代变量,因此当修改迭代变量的值时对集合元素本身没有任何影响
注意: 当使用Iterator迭代访问Collection集合元素时,Collection集合里的元素不能被改变,只能通过Iterator的remove方法删除上一次next方法返回的集合元素,否则将会引发 java.util.CencurrentModificationException异常。
1 import java.util.*; 2publicclass IteratorDemo { 3 4publicstaticvoid main(String[] args) { 5 6// 创建一个集合 7 Collection books = new HashSet(); 8 books.add("三国演义"); 9 books.add("西游记"); 10 books.add("水浒传"); 1112// 获取books集合对应的迭代器13 Iterator it = books.iterator(); 14while (it.hasNext()) { 15// it.next()方法返回的是Object类型,需强制类型转换16 String str = (String) it.next(); 17 System.out.println(str); 1819if (str.equals("三国演义")) { 20// 从集合中删除上一次next方法返回的元素21 it.remove();// 通过迭代器删除 2223// 不要使用集合自身所带的remove方法,会引发异常 24// books.remove(str);25 } 26// 对str变量赋值,不会改变集合元素本身27 str = "红楼梦";// 此处代码对集合没有任何影响28 } 29 System.out.println(books);// [西游记, 水浒传]30 } 31 }
boolean contains(Object o):判断集合中是否包含某个元素
存储在集合中的元素应该重写equals方法
1 import java.util.*; 2publicclass ContainsDemo { 3 4publicstaticvoid main(String[] args) { 5 6// 创建集合 7 Collection c = new ArrayList(); 8 9// 创建Integer类型对象10 Integer i1 = new Integer(100); 1112// 添加元素13 c.add(i1); 1415// 判断集合中是否包含i116 System.out.println(c.contains(i1));// true 1718// 创建另一个Integer类型对象19 Integer i2 = new Integer(100); 20// contains方法底层调用的是equals方法。Integer重写了equals方法,i1就是i221 System.out.println(c.contains(i2));// true 2223// 创建一个Student对象24 Student s1 = new Student(100, "Bill"); 25// 添加到集合里26 c.add(s1); 27// 判断集合c中是否包含s128 System.out.println(c.contains(s1));// true 2930// 创建另一个Student对象31 Student s2 = new Student(100, "Bill"); 32// 重写equals方法之前,比较的是内存 33// System.out.println(c.contains(s2));//false 3435// 重写equals方法之后,比较的是内容36 System.out.println(c.contains(s2));// true37 } 38} 3940class Student { 41int no; 42 String name; 4344 Student(int no, String name) { 45this.no = no; 46this.name = name; 47 } 4849// 重写equals方法 50// 要求:编号和姓名相同则表示同一个Student51publicboolean equals(Object o) { 52if (this == o) { 53returntrue; 54 } 55if (o instanceof Student) { 56 Student s = (Student) o; 57if (s.no == this.no && s.name == this.name) { 58returntrue; 59 } 60 } 61returnfalse; 62 } 63 }
List集合
ArrayList集合底层是数组。数组是有下标的. 所以ArrayList集合有很多自己的特性.
ArrayList集合底层默认初始化容量是 10. 扩大之后的容量是原容量的1.5倍.
Vector集合底层默认初始化容量也是10.扩大之后的容量是原容量的2倍.
如何优化ArrayList和Vector?
尽量减少扩容操作,因为扩容需要数组拷贝。数组拷贝很耗内存。一般推荐在创建集合的时候指定初始化容量。
1 import java.util.*; 2publicclass ListDemo { 3 4publicstaticvoid main(String[] args) { 5 6// 创建List集合 7 List li = new ArrayList(); 8// List li = new LinkedList(); 910// 添加元素11 li.add(100); 12 li.add(200); 13 li.add(400); 1415// 在下标为2的位置上添加30016 li.add(2, 300); 1718// 取得第一个元素19 System.out.println(li.get(0));// 100 2021// 遍历(List集合特有的遍历方式)22for (int i = 0; i < li.size(); i++) { 23 Object o = li.get(i); 24 System.out.println(o); 25 } 2627// 迭代器也可以28 Iterator it = li.iterator(); 29while (it.hasNext()) { 30 System.out.println(it.next()); 31 } 32 } 33 }
Set集合:HashSet
1.HashSet底层实际上是一个HashMap,HashMap底层采用了哈希表数据结构。
2.哈希表又叫做散列表,哈希表底层是一个数组,这个数组中每一个元素是一个单向链表。每个单向链表都有一个独一无二的hash值,代表数组的下标。在某个单向链表中的每一个节点上的hash值是相等的。hash值实际上是key调用hashCode方法,在通过"hash function"转换成的值。
3.如何向哈希表中添加元素:先调用被存储的key的hashCode方法,经过某个算法得出hash值,如果在这个哈希表中不存在这个 hash值,则直接加入元素。如果该hash值已经存在,继续调用key之间的equals方法,如果equals方法返回false,则将该元素添加。如果equals方法返回true,则放弃添加该元素。
4.HashSet其实是HashMap中的key部分。HashSet有什么特点,HashMap中的key 应该具有相同的特点。
5.HashMap和HashSet初始化容量都是 16,默认加载因子是0.75,即当存储容量达到75%时就扩容。
6.关于往Set集合中存储的元素,该元素的hashCode和equals方法:
HashMap中有一个put方法,put(key,value) key是无序不可重复的.
结论:存储在HashSet集合或者HashMap集合key部分的元素,需要同时重写hashCode+equals
1 import java.util.*; 2publicclass SetDemo { 3 4publicstaticvoid main(String[] args) { 5 6// Set集合存储元素是无序不可重复的,这里就不做测试了 7 8//创建集合 9 Set s = new HashSet(); 1011//这里假设键值重复只为做测试,实际上是不可重复的12 Employee e1 = new Employee("1000","JACK"); 13 Employee e2 = new Employee("1000","JACK"); 14 Employee e3 = new Employee("1000","SCOTT"); 15 Employee e4 = new Employee("2001","SUN"); 16 Employee e5 = new Employee("3000","JIM"); 17 Employee e6 = new Employee("3001","COOK"); 1819 System.out.println(e1.hashCode());//重写hashCode方法后e1就是e220 System.out.println(e2.hashCode()); 2122//添加元素23 s.add(e1); 24 s.add(e2); 25 s.add(e3); 26 s.add(e4); 27 s.add(e5); 28 s.add(e6); 2930//查看集合元素个数31 System.out.println(s.size()); //53233 } 34} 3536//假设该公司员工编号是: 1000 - 999937class Employee{ 3839//编号40 String no; 4142//姓名43 String name; 4445//Constructor46 Employee(String no,String name){ 47this.no = no; 48this.name = name; 49 } 5051//重写equals方法. 52//如果员工编号相同,并且名字相同,则是同一个对象53publicboolean equals(Object o){ 54if(this==o){ 55returntrue; 56 } 57if(o instanceof Employee){ 58 Employee e = (Employee)o; 59if(e.no.equals(this.no) && e.name.equals(this.name)){ 60returntrue; 61 } 62 } 6364returnfalse; 65 } 6667//重写hashCode方法.68publicint hashCode(){ 69//以员工编号分组.70return no.hashCode(); 71 } 72 }
先对SortedSet做测试
1 import java.text.*; 2import java.util.*; 3 4publicclass SortedSetDemo01 { 5 6publicstaticvoid main(String[] args) throws Exception { 7 8// 创建集合 9 SortedSet ss = new TreeSet(); 1011// 测试Integer类型12 ss.add(10); // 自动装箱13 ss.add(20); 14 ss.add(15); 15 ss.add(30); 16 ss.add(25); 17 ss.add(9); 1819// 遍历20 Iterator it = ss.iterator(); 21while (it.hasNext()) { 22 Object element = it.next(); 23 System.out.println(element);//9 10 15 20 25 3024 } 2526// 测试String类型27 SortedSet strs = new TreeSet(); 2829 strs.add("JACK"); 30 strs.add("SUN"); 31 strs.add("KOOK"); 32 strs.add("LUCY"); 33 strs.add("KING"); 3435// 遍历36 it = strs.iterator(); 37while (it.hasNext()) { 38 Object element = it.next(); 39 System.out.println(element); 40/*输出:JACK 41 KING 42 KOOK 43 LUCY 44 SUN*/45 } 4647// 测试日期Date类型48 String st1 = "2008-08-08"; 49 String st2 = "2009-08-08"; 50 String st3 = "2008-09-08"; 51 String st4 = "2008-08-09"; 52 String st5 = "2012-08-08"; 5354 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 5556 Date t1 = sdf.parse(st1); 57 Date t2 = sdf.parse(st2); 58 Date t3 = sdf.parse(st3); 59 Date t4 = sdf.parse(st4); 60 Date t5 = sdf.parse(st5); 6162// 添加63 SortedSet times = new TreeSet(); 6465 times.add(t5); 66 times.add(t2); 67 times.add(t3); 68 times.add(t4); 69 times.add(t1); 7071// 遍历72 it = times.iterator(); 73while (it.hasNext()) { 74 Object element = it.next(); 75if (element instanceof Date) { 76 Date d = (Date) element; 7778 System.out.println(sdf.format(d)); 79/*输出:2008-08-08 80 2008-08-09 81 2008-09-08 82 2009-08-08 83 2012-08-08*/84 } 85 } 86 } 87 }
SortedSet集合存储元素为什么可以自动排序?
因为被存储的元素实现了Comparable接口,
SUN编写TreeSet集合在添加元素的时候,会调用compareTo方法完成比较.
1 import java.util.*; 2 3publicclass SortedSetDemo02 { 4 5publicstaticvoid main(String[] args) { 6 7 SortedSet users = new TreeSet(); 8 9 User u1 = new User(15); 10 User u2 = new User(16); 11 User u3 = new User(25); 12 User u4 = new User(13); 13 User u5 = new User(11); 1415// 添加元素16 users.add(u1); 17 users.add(u2); 18 users.add(u3); 19 users.add(u4); 20 users.add(u5); 2122// 遍历23 Iterator it = users.iterator(); 24while (it.hasNext()) { 25//输出:User[age=11] User[age=13] User[age=15] User[age=16] User[age=25]26 System.out.println(it.next()); 27 } 28 } 2930} 3132// 这是第一种方式.33class User implements Comparable { 3435int age; 3637 User(int age) { 38this.age = age; 39 } 4041public String toString() { 42return "User[age=" + age + "]"; 43 } 4445// 实现java.lang.Comparable;接口中的compareTo方法 46// 该方法程序员负责实现,SUN提供的程序已经调用了该方法. 47// 需求:按照User的age排序48publicint compareTo(Object o) { 49// 编写一个比较规则.50int age1 = this.age; 51int age2 = ((User) o).age; 52return age1 - age2; 53 } 54 }
让SortedSet集合做到排序还有另一种方式:java.util.Comparator;
单独编写一个比较器.
1 import java.util.*; 2 3publicclass SortedSetDemo03 { 4 5publicstaticvoid main(String[] args) { 6 7// 创建TreeSet集合的时候提供一个比较器. 8 SortedSet products = new TreeSet(new ProductComparator()); 910// 匿名内部类:不推荐使用,因为比较器无法得到重复利用。11/*12 * SortedSet products = new TreeSet(new Comparator() { // 需求:按照商品价格排序 13 * public int compare(Object o1, Object o2) { 14 * 15 * double price1 = ((Product) o1).price; double price2 = ((Product) 16 * o2).price; 17 * 18 * if (price1 == price2) { return 0; } else if (price1 > price2) { 19 * return 1; } else { return -1; } } }); 20*/2122 Product p1 = new Product(3.4); 23 Product p2 = new Product(4.0); 24 Product p3 = new Product(3.0); 25 Product p4 = new Product(2.0); 26 Product p5 = new Product(5.0); 2728// 添加元素29 products.add(p1); 30 products.add(p2); 31 products.add(p3); 32 products.add(p4); 33 products.add(p5); 3435// 遍历36 Iterator it = products.iterator(); 37while (it.hasNext()) { 38//输出2.0 3.0 3.4 4.0 5.039 System.out.println(it.next()); 4041 } 42 } 4344} 4546class Product { 4748double price; 4950 Product(double price) { 51this.price = price; 52 } 5354public String toString() { 55return price + ""; 56 } 5758} 5960// 第二种方法单独编写一个比较器6162class ProductComparator implements Comparator { 6364// 需求:按照商品价格排序65publicint compare(Object o1, Object o2) { 6667double price1 = ((Product) o1).price; 68double price2 = ((Product) o2).price; 6970if (price1 == price2) { 71return 0; 72 } elseif (price1 > price2) { 73return 1; 74 } else { 75return -1; 76 } 77 } 7879 }
下面是集合继承结构图-Map部分,从图中可以清楚的知道Map接口下子接口与实现类的关系。
关于Map集合中常用的方法
void clear(); 清空Map
boolean isEmpty();判断该集合是否为空
int size(); 获取Map中键值对的个数。
Object put(Object key, Object value); 向集合中添加键值对
Object get(Object key);通过key获取value
boolean containsKey(Object key); 判断Map中是否包含这样的key
boolean containsValue(Object value); 判断Map中是否包含这样的value
Object remove(Object key); 通过key将键值对删除.
Collection values(); 获取Map集合中所有的value
Set keySet(); 获取Map中所有的key
Set entrySet();返回此映射中包含的映射关系的 Set 视图。
注意:存储在Map集合key部分的元素需要同时重写hashCode+equals方法.
1 import java.util.*; 2 3publicclass MapDemo01{ 4 5publicstaticvoid main(String[] args){ 6 7//1.创建Map集合 8 Map persons = new HashMap(); //HashMap的默认初始化容量是16,默认加载因子是0.75 910//2.存储键值对11 persons.put("10000","JACK"); 12 persons.put("10011","JACK"); 13 persons.put("10002","SUN"); 14 persons.put("10003","COOK"); 15 persons.put("10004","KING"); 16 persons.put("10000","LUCY"); 1718//3.判断键值对的个数 19//Map中的key是无序不可重复的.和HashSet相同.20 System.out.println(persons.size());//5 2122//4.判断集合中是否包含这样的key23 System.out.println(persons.containsKey("10000")); //true 2425//5.判断集合中是否包含这样的value 26//注意:Map中如果key重复了,value采用的是“覆盖”。27 System.out.println(persons.containsValue("LUCY")); //true 2829//6.通过key获取value30 String k = "10002"; 31 Object v = persons.get(k); 32 System.out.println(v); //SUN 3334//7.通过key删除键值对35 persons.remove("10002"); 36 System.out.println(persons.size()); //4 3738//8.获取所有的value39 Collection values = persons.values(); 40 Iterator it = values.iterator(); 41while(it.hasNext()){ 42 System.out.println(it.next()); 43/*LUCY 44 JACK 45 COOK 46 KING*/47 } 4849//9.获取所有的key 50//以下程序演示如何遍历Map集合.51 Set keys = persons.keySet(); 5253 Iterator it2 = keys.iterator(); 5455while(it2.hasNext()){ 56 Object id = it2.next(); 57 Object name = persons.get(id); 58 System.out.println(id+"-->"+name); 59/*10000-->LUCY 60 10011-->JACK 61 10003-->COOK 62 10004-->KING*/6364 } 6566//10.entrySet 67//将Map转换成Set集合.68/*69 Set entrySet = persons.entrySet(); 70 Iterator it3 = entrySet.iterator(); 71 while(it3.hasNext()){ 72 System.out.println(it3.next()); 73 } 74*/7576 } 77 }
使用集合的技巧:
看到Array就是数组结构,有角标,查询速度很快。
看到link就是链表结构:增删速度快,而且有特有方法。addFirst; addLast; removeFirst(); removeLast(); getFirst();getLast();
看到hash就是哈希表,就要想要哈希值,就要想到唯一性,就要想到存入到该结构的中的元素必须覆盖hashCode,equals方法。
看到tree就是二叉树,就要想到排序,就想要用到比较。
比较的两种方式:
一个是Comparable:覆盖compareTo方法;
一个是Comparator:覆盖compare方法。
LinkedHashSet,LinkedHashMap:这两个集合可以保证哈希表有存入顺序和取出顺序一致,保证哈希表有序。
这是我在自学到java集合时通过看视频所整理出来的一部分内容,马马虎虎。在此感谢授课老师将视频分享,让在黑暗中摸索的我看到了一丝光明。把自己学到的一些知识分享出来是快乐的,这样也能鞭策自己,磨砺自己。所谓当局者迷,旁观者清,在此还望各位前辈不吝赐教,指出不足之处,这样我也才能更好的认清自己。下面附上我所看视频的下载地址:http://pan.baidu.com/s/1i342Y6x
原文:http://www.cnblogs.com/zhimu/p/4563205.html
内容总结
以上是互联网集市为您收集整理的java基础——集合全部内容,希望文章能够帮你解决java基础——集合所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。