JAVA基础--容器 Set, List, Map
Colections接口, Iterator接口, Set接口, List接口, Comparable接口, Map接口
Collections类
容器:装各种对象. 所有容器都在java.util里. Set, List, Map
1136:
1一个图:
Collection接口分为Set和List两个接口
Set接口: 没有顺序并且不可以重复 equals判断是否可重复
List接口: 有顺序并且可以重复
Map接口定义了存储 key-value映射对的方法
Collection接口
Set接口 List接口 Map接口
HashSet LinkedList ArrayList HashMap
1个类:Collections
3个知识点:for, generic, auto-boxing/unboxing
6个接口: Collection, Set,List, Map, Iterator, Comparable.
Collection接口所定义的方法:
size(), isEmpty(),clear(),contains(), add(), remove(),iterator(),containsAll(), addAll(), removeAll(),retainAll(), toArray()
容器类对象在调用remove,contains等方法时需要比较对象是否相等, 就会涉及到equals和hashCode方法.对于自定义的类需要重写这两个方法.
hashCode会用于对象用于索引的时候, 比如Map的key值.
Collection方法举例:
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 30 31 32 33 34 35 36 37 38 39 40 | import java.util.*; class Name{ private String firstName, lastName; public Name(String firstName, String lastName){ this .firstName=firstName; this .lastName=lastName; } public String getFirstName(){ return firstName; } public String getLastName(){ return lastName; } public String toString(){ return firstName+ " " +lastName; } public boolean equals(Object obj){ if (obj instanceof Name){ Name name =(Name) obj; return (firstName.equals(name.firstName))&&(lastName.equals(name.lastName)); } return super .equals(obj); } public int hashCode(){ return firstName.hashCode(); } } public class Test{ public static void main(String[] args){ Collection c = new ArrayList(); //父类引用调用子类对象 c.add( "hello" ); c.add( new Name( "f1" , "l1" )); c.add( new Integer( 100 )); //不用基本类型的原因, int类型数据是存放在栈里的 c.remove( "hello" ); c.remove( new Integer( 100 )); System.out.println(c.size()); System.out.println(c.remove( new Name( "f1" , "l1" ))); //重写equals方法,所以可以删掉上面add的那个 System.out.println(c); } } |
Iterator接口: 容器里的元素挨个取出来. 最常用!!!!!
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class Test { public static void main(String[] args){ Collection c = new HashSet(); c.add( new Name( "f1" , "l1" )); c.add( new Name( "f2" , "l2" )); c.add( new Name( "f3" , "l3" )); Iterator i = c.iterator(); while (i.hasNext()){ Name n = (Name)i.next(); System.out.println(n.getFirstName()+ " " +n.getLastName()); } } } |
remove()方法是迭代过程中删除元素唯一安全的方法 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class Test { public static void main(String[] args){ Collection c = new HashSet(); c.add( new Name( "fff1" , "lll1" )); c.add( new Name( "f2" , "l2" )); c.add( new Name( "ffff3" , "llll3" )); for (Iterator i = c.iterator(); i.hasNext();){ Name n = (Name)i.next(); if (n.getFirstName().length()< 3 ){ i.remove(); //不能用c.remove(name); , 会产生例外 } } System.out.println(c); } } |
for循环用于遍历容器集合,但是除了简单遍历并读出其中内容外, 不建议使用增强for:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import java.util.*; public class EnhanceFor { public static void main(String[] args){ int [] arr={ 1 , 2 , 3 , 4 , 5 }; for ( int i:arr){ System.out.println(i); } Collection c = new ArrayList(); c.add( new String( "aaa" )); c.add( new String( "bbb" )); c.add( new String( "ccc" )); for (Object o : c){ System.out.println(o); } } } |
缺点:
1.数组: 无法访问下标值.
2. 集合: 与使用Iterator相比, 不能方便删除集合中的内容.
Set接口的容器类:Hashset:
1 2 3 4 5 6 7 8 9 | public class Test{ public static void main(String[] args){ Set s= new HashSet(); //父类引用调用子类对象 s.add( "hello" ); s.add( "world" ); s.add( new Name( "f1" , "l1" )); s.add( new Integer( 100 )); //不用基本类型的原因, int类型数据是存放在栈里的 s.add( new Name( "f1" , "l1" )); //重复元素不会加入 s.add( "hello" ); //重复元素不会加入System.out.println(s); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class Test{ public static void main(String[] args){ Set s1= new HashSet(); //父类引用调用子类对象 Set s2= new HashSet(); //父类引用调用子类对象 s1.add( "a" ); s1.add( "b" ); s1.add( "c" ); s2.add( "d" ); s2.add( "a" ); s2.add( "b" ); Set sn= new HashSet(s1); sn.retainAll(s2); //求交集 Set su= new HashSet(s1); su.addAll(s2); //加起来, 重复去掉 System.out.println(sn); System.out.println(su); } } |
List接口的容器类: ArrayList, LinkedList
List方法举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import java.util.*; public class Test { public static void main(String[] args){ List l1 = new LinkedList(); for ( int i = 0 ;i<= 5 ;i++){ l1.add( "a" +i); } System.out.println(l1); l1.add( 3 , "a100" ); System.out.println(l1); l1.set( 6 , "a200" ); System.out.println(l1); System.out.println((String)l1.get( 2 )+ " " ); System.out.println(l1.indexOf( "a3" )); l1.remove( 1 ); System.out.println(l1); } } |
结果:
1 2 3 4 5 6 | [a0, a1, a2, a3, a4, a5] [a0, a1, a2, a100, a3, a4, a5] [a0, a1, a2, a100, a3, a4, a200] a2 4 [a0, a2, a100, a3, a4, a200] |
一个类:Collections: 提供一些静态方法实现基于List容器的算法
还有其他方法:
void sort(List): 排序
void shuffle(List):随机排序
void reverse(List): 逆序排序
void fill(List,Object), 用一个特定对象重写整个List容器
void copy(List dest,List src);
int binarySearch(List,Object); 折半查找
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import java.util.*; public class Test { public static void main(String[] args){ List l1 = new LinkedList(); List l2 = new LinkedList(); for ( int i = 0 ;i<= 9 ;i++){ l1.add( "a" +i); } System.out.println(l1); Collections.shuffle(l1); System.out.println(l1); Collections.reverse(l1); System.out.println(l1); Collections.sort(l1); System.out.println(l1); System.out.println(Collections.binarySearch(l1, "a5" )); } } |
结果:
1 2 3 4 5 | [a0, a1, a2, a3, a4, a5, a6, a7, a8, a9] [a1, a5, a3, a2, a7, a0, a9, a8, a6, a4] [a4, a6, a8, a9, a0, a7, a2, a3, a5, a1] [a0, a1, a2, a3, a4, a5, a6, a7, a8, a9] 5 |
对类进行排序, 两个对象可以比较大小: Comparable接口: java.lang.Comparable
此接口只有一个方法:
public int compareTo(Object obj);
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | import java.util.*; class Name implements Comparable{ private String firstName, lastName; public Name(String firstName, String lastName){ this .firstName=firstName; this .lastName=lastName; } public String getfirstName(){ return firstName; } public String getlastName(){ return lastName; } public String toString(){ return firstName+ " " +lastName; } public boolean equals(Object obj){ if (obj instanceof Name){ Name name =(Name) obj; return (firstName.equals(name.firstName))&&(lastName.equals(name.lastName)); } return super .equals(obj); } public int hashCode(){ return firstName.hashCode(); } public int compareTo(Object o){ Name n = (Name) o; int lastCmp=lastName.compareTo(n.lastName); return (lastCmp!= 0 ?lastCmp:firstName.compareTo(n.firstName)); } } public class Test{ public static void main(String[] args){ List l1= new LinkedList(); l1.add( new Name( "Karl" , "M" )); l1.add( new Name( "Steven" , "Lee" )); l1.add( new Name( "John" , "O" )); l1.add( new Name( "Tom" , "M" )); System.out.println(l1); Collections.sort(l1); //调用上面的compareTo方法 System.out.println(l1); } } |
如何衡量标准:读和改的效率:
Array:读快改慢
Linked:改快读慢
Hash:两者之间
Map接口:实现类: HashMap, TreeMap
Map中的键值通过键来标示, 键值不能重复, 必须重写equals和hashCode方法
常用方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Object put(Object key, Object value); //如果放入了已经存在的一个key, 那么新的value会替换掉原来的value, 所以会返回原来的value Object get(Object key); //通过key找到value Object remove(Object key); boolean containsKey(Object key); boolean containsValue(Object value); int size(); boolean isEmpty(); void putAll(Map t); void clear(); |
Map方法举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import java.util.*; public class EnhanceFor { public static void main(String[] args){ Map m1= new HashMap(); Map m2= new TreeMap(); m1.put( "one" , new Integer( 1 )); m1.put( "two" , new Integer( 2 )); m1.put( "three" , new Integer( 3 )); m2.put( "A" , new Integer( 1 )); m2.put( "B" , new Integer( 2 )); System.out.println(m1.size()); System.out.println(m1.containsKey( "one" )); System.out.println(m2.containsValue( new Integer( 1 ))); if (m1.containsKey( "two" )){ int i=((Integer)m1.get( "two" )).intValue(); System.out.println(i); } Map m3= new HashMap(m1); m3.putAll(m2); System.out.println(m3); } } |
自动Boxing和Unboxing后上述程序可以改成这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import java.util.*; public class TestMap { public static void main(String[] args){ Map m1= new HashMap(); Map m2= new TreeMap(); m1.put( "one" , 1 ); //自动boxing m1.put( "two" , 2 ); m1.put( "three" , 3 ); m2.put( "A" , 1 ); m2.put( "B" , 2 ); System.out.println(m1.size()); System.out.println(m1.containsKey( "one" )); System.out.println(m2.containsValue( 1 )); if (m1.containsKey( "two" )){ int i=(Integer)m1.get( "two" ); System.out.println(i); } Map m3= new HashMap(m1); m3.putAll(m2); System.out.println(m3); } } |
结果:
1 2 3 4 5 | 3 true true 2 {two= 2 , A= 1 , B= 2 , one= 1 , three= 3 } |
泛型: 定义集合的时候同时定义集合中对象的类型, 可以在定义Collection的时候指定, 也可以在循环的时候用Iterator指定, 这样可以增强程序的可读性和稳定性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public class Test{ public static void main(String[] args){ List<String> c= new ArrayList<String>(); c.add( "aaa" ); c.add( "bbb" ); c.add( "ccc" ); for ( int i= 0 ;i<c.size();i++){ String s=c.get(i); System.out.println(s); } Collection<String> c2= new HashSet<String>(); c2.add( "aaa" ); c2.add( "bbb" ); c2.add( "ccc" ); for (Iterator<String> it=c2.iterator();it.hasNext();){ String s=it.next(); System.out.println(s); } } } |
用泛型改写Map的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import java.util.*; public class TestMap { public static void main(String[] args){ Map<String,Integer> m1= new HashMap<String,Integer>(); m1.put( "one" , 1 ); m1.put( "two" , 2 ); m1.put( "three" , 3 ); System.out.println(m1.size()); System.out.println(m1.containsKey( "one" )); if (m1.containsKey( "two" )){ int i=m1.get( "two" ); System.out.println(i); } } } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步