前言:
在写程序当中,集合会经常使用,今天听了马老师的课,写一些自己的总结
正文:
集合最重要的就是一个图,一个类,三个知识点,六个接口
说到图就是上面的图,这个图可以帮我们理解这些接口的继承关系
1.容器 API
Collection接口
定义了存取一组对象的方法,其子接口Set和List分别定义了储存方式:
-
- Set中的对象没有顺序可以重复
- List的对象有顺序不可重复
Collection接口定义的方法(一个一个往里面存)(可以在API中查到,在这就不一一阐述了,仅仅列举一些)
1 import java.util.*;; 2 3 public class TestCollection{ 4 int i; 5 public TestCollection(int i) { 6 this.i=i; 7 8 } 9 public static void main(String[] args) { 10 Collection c=new ArrayList(); 11 c.add("hello"); 12 c.add(new Integer(1)); 13 System.out.println(c.size()); 14 System.out.println(c); 15 } 16 17 }
输出:
2 [hello, 1]
问题1:为什么在代码中加高亮的区域用Collection c=new ArrayList();而不用ArrayList c=new ArrayList();
答案:使用Collection接口就不会调用ArrayList的专用方法,这在以后如果想把ArrayList改成别的就会非常灵活
容器类对象调用remove和contains方法时,会调用equals和hashCode方法,对于自定义的类型要重写equals和hashCode方法以实现自定义对象的相等规则
注意:相等的对象有相等的hashCode
增加equals和hashCode方法方法如下(我在ADhero类中重写上面两种方法,在TestCollection中调用)
1 public class ADHero { 2 String name; 3 public ADHero(String name) { 4 this.name=name; 5 } 6 public boolean equals(Object obj) { 7 // TODO Auto-generated method stub 8 if(obj instanceof ADHero) { 9 ADHero a=(ADHero) obj; 10 return(name.equals(a.name)); 11 } 12 return(super.equals(obj)); 13 } 14 public int hashCode() { 15 return name.hashCode();//直接让字符串来实现hashCode方法,因为字符串已经重写了hashCode方法 16 } 17 }
TestCollection类中的方法
1 import java.util.*;; 2 3 public class TestCollection { 4 public static void main(String[] args) { 5 System.out.println(new ADHero("奥巴马").equals(new ADHero("奥巴马"))); 6 } 7 8 }
输出为:true
Iterator接口
所有实现Collection接口的容器类,都有一个iterator方法用以返回实现了Tterator接口的对象
Iterator对象称为迭代器,用以方便的对容器内的元素遍历操作
Iterator接口定义了如下方法
boolean hasNext(); //判断游标右边是否有元素
Object next(); //返回 游标右边的元素,并把游标移动到下一个位置
void remove;
Iterator方法举例
1 import java.util.*;; 2 public class TestCollection { 3 public static void main(String[] args) { 4 Collection c = new HashSet(); 5 c.add(new ADHero("德莱文")); 6 c.add(new ADHero("奥巴马")); 7 c.add(new ADHero("迅捷斥侯")); 8 c.add(new ADHero("探险家")); 9 Iterator i = c.iterator(); 10 while (i.hasNext()) { 11 ADHero adc = (ADHero) i.next(); 12 System.out.println(adc.name); 13 } 14 15 } 16 17 }
输出
迅捷斥侯 奥巴马 探险家 德莱文
Iterator对象的remove方法是在迭代过程中删除元素的唯一方式
代码如下所示
ADHero类
1 public class ADHero { 2 String name; 3 4 public ADHero(String name) { 5 this.name = name; 6 } 7 8 public String getName() { //遇到输出的不是名字,而是id而重写的方法 9 return this.name = name; 10 } 11 12 public String toString() { 13 return this.name = name; 14 } 15 16 public boolean equals(Object obj) { 17 // TODO Auto-generated method stub 18 if (obj instanceof ADHero) { 19 ADHero a = (ADHero) obj; 20 return (name.equals(a.name)); 21 } 22 return (super.equals(obj)); 23 } 24 25 public int hashCode() { 26 return name.hashCode(); 27 } 28 }
TestCollection 类
1 import java.util.*;; 2 3 public class TestCollection { 4 public static void main(String[] args) { 5 Collection c = new HashSet(); 6 c.add(new ADHero("德莱文")); 7 c.add(new ADHero("奥巴马")); 8 c.add(new ADHero("迅捷斥侯")); 9 c.add(new ADHero("探险家")); 10 for (Iterator i = c.iterator(); i.hasNext();) { 11 ADHero adc = (ADHero) i.next(); 12 if (adc.getName().length() >3 ) { 13 i.remove(); 14 15 } 16 17 } 18 19 System.out.println(c); 20 21 } 22 23 }
Set接口
Set接口是Collection的子接口, Set接口没有提供额外的方法,但实现Set接口的容器类的元素是没有顺序且不能重复, Set接口提供的容器类有hashSet和treeSet
Set接口方法举例1
1 import java.util.*;; 2 3 public class TestCollection { 4 public static void main(String[] args) { 5 Set s=new HashSet(); 6 s.add(new ADHero("奥巴马")); 7 s.add(new ADHero("皮城女警")); 8 s.add(new ADHero("暴走萝莉")); 9 s.add(new ADHero("暴走萝莉"));//相同元素不会被加入 10 s.add(new ADHero("皮城女警"));//相同元素不会被加入 11 System.out.println(s); 12 } 13 }
输出:
皮城女警, 奥巴马, 暴走萝莉]
Set接口方法举例2
1 import java.util.*;; 2 3 public class TestCollection { 4 public static void main(String[] args) { 5 Set s1=new HashSet(); 6 Set s2=new HashSet(); 7 s1.add(new ADHero("奥巴马")); 8 s1.add(new ADHero("皮城女警")); 9 s1.add(new ADHero("暴走萝莉")); 10 s2.add(new ADHero("奥巴马")); 11 s2.add(new ADHero("皮城女警")); 12 s2.add(new ADHero("赏金猎人")); 13 Set s3=new HashSet(s1); 14 s3.retainAll(s2); 15 System.out.println(s3); 16 Set s4=new HashSet(); 17 s4.addAll(s2); 18 System.out.println(s4); 19 } 20 }
输出:
[皮城女警, 奥巴马] [赏金猎人, 皮城女警, 奥巴马]
List接口
List接口是Collection的子接口,实现List接口的容器类元素是有顺序的,而且可以重复
List容器中的元素都对应一个整数型的序号记载其在容器内的位置,可以根据序号存取容器内的元素
List容器类有LinkLIst和ArrayList
List接口的方法及其方法的类型
代码如下
1 import java.util.*;; 2 3 public class TestCollection { 4 public static void main(String[] args) { 5 List l1 = new LinkedList(); 6 for (int i = 0; i <= 9; i++) { 7 l1.add("a" + i); 8 } 9 System.out.println(l1); 10 // 把2位置的元素设置成a100 11 l1.set(2, "a100"); 12 System.out.println(l1); 13 // 得到3位置上的元素 14 System.out.println(l1.get(3)); 15 // 得到a6的位置 16 System.out.println(l1.indexOf("a6")); 17 // 删掉3位置上的元素 18 l1.remove(3); 19 System.out.println(l1); 20 } 21 }
输出
[a0, a1, a2, a3, a4, a5, a6, a7, a8, a9] [a0, a1, a100, a3, a4, a5, a6, a7, a8, a9] a3 6 [a0, a1, a100, a4, a5, a6, a7, a8, a9]
List常用的算法
类java.util.Collection提供一些静态方法实现基于List容器的方法
代码:
1 import java.util.*;; 2 3 public class TestCollection { 4 public static void main(String[] args) { 5 List l1 = new LinkedList(); 6 for (int i = 0; i <= 9; i++) { 7 l1.add("a" + i); 8 } 9 // 随机排序 10 Collections.shuffle(l1); 11 System.out.println(l1); 12 // 逆序 13 Collections.reverse(l1); 14 System.out.println(l1); 15 // 排序 16 Collections.sort(l1); 17 System.out.println(l1); 18 // 使用二分法查找 19 System.out.println(Collections.binarySearch(l1, "a5")); 20 } 21 }
输出:
[a2, a1, a3, a6, a0, a7, a5, a9, a8, a4]
[a4, a8, a9, a5, a7, a0, a6, a3, a1, a2]
[a0, a1, a2, a3, a4, a5, a6, a7, a8, a9]
5
Comparble接口
问题:上面的排序中什么确定容器中的“大小”顺序?
所有可以实现排序的类都可以实现java.lang.Comparable接口,此接口中只有一个方法
1 public void compareTo(Object obj){}
该方法返回值
- 返回 0 表示this=obj
- 返回正数 表示this>obj
- 返回负数 表示this<obj
实现了Comparable接口通过实现compareTo方法从而确定该类对象的排序方式
Map接口定义了储存键(key)-值(value)对的方法(一对一对往里面存)
如何选择数据结构
衡量的标准;读的效率和写的效率
Array读快写满
Linked改快读慢
Hash两者之间
Map接口
实现Map接口的类用来储存键-值对
Map接口的实现类有HashMap和TreeMap
Map接口中储存的键-值对有键来标识,所以键不能重复
下面是Map接口的部分方法,具体作用可以查找API文档
代码小练习
1 public class TestCollection { 2 public static void main(String[] args) { 3 Map<String, Integer> m1 = new HashMap<String, Integer>(); 4 Map<String, Integer> m2 = new TreeMap<String, Integer>(); 5 m1.put("one", 1); 6 m1.put("two", 2); 7 m1.put("three", 3); 8 m2.put("a", 4); 9 m2.put("b", 5); 10 // 数量 11 System.out.println(m1.size()); 12 System.out.println(m2.size()); 13 if (m1.containsKey("two")) { 14 int i = m1.get("two"); 15 System.out.println(i); 16 } 17 // m1除掉key值为one的值 18 System.out.println(m1.remove("one")); 19 Map m3 = new HashMap(m2); 20 // m1复制到m3 21 m3.putAll(m1); 22 System.out.println(m3); 23 } 24 }
定义集合时可以同时定义对象的类型,如上面代码所示,这样定义就可不用强制转换,在key中只能是字符串,value只能是数字
来源:https://www.cnblogs.com/z-cg/p/12271341.html