推荐链接:
Java集合
终于有人把 HashMap 说清楚了,面试不再怕的!
集合继承体系图
对象数组 1、数组既可以存储基本数据类型,也可以存储引用类型。存储引用类型时的数组就叫对象数组。
2、案例:
3、对象数组的内存图解:
集合结构及特点 常用集合的特征 i. Set集合:不能保存重复值,不保存元素加入的顺序。
ii. List集合:可以保存重复值,保存元素加入的顺序。
iii. Map集合:保存一个键值对(Key-Value),键不能重复,值可以重复 。
Set集合 i. java.util.TreeSet类:集合中的元素以升序排序 。创建集合不能指定集合的长度。
ii. java.util.HashSet类:集合中的元素根据哈希值进行排序 。创建集合时可以指定集合的长度,长度不够时默认以75%的比例增加长度。
List集合 **i. ArrayList:线性数据结构。根据位置获得元素效率高,添加与删除元素时效率低。**创建集合时可以指定集合的长度。
**ii. LinkedList:链表数据结构。添加与删除元素时效率高,根据位置获得元素时效率低。**创建集合时不能指定集合的长度。
iii. Vector:功能与ArrayList完全一致。Vector是线程安全的,ArrayList是线程不安全的。
Map集合 i. Hashtable:线程安全的。不允许使用null作为键或值。
ii. HashMap:线程不安全的。允许使用null作为键或值。
TreeSet 和 TreeMap 共性 : 使用元素的自然顺序 对元素进行排序 ,或者根据创建集合时提供的 Comparator 进行排序,具体取决于使用的构造方法。总之,元素或集合必须要有比较性 。
a:自然排序 (元素具备比较性)
让存储的元素所属的类 实现自然排序接口:Comparable接口
b:比较器排序 (集合具备比较性)
让集合构造方法接收Comparator的实现类对象
泛型 从JDK1.5开始出现
i. 在后期绑定数据类型。
ii. 如果不指定泛型,默认为Object类型。
iii. 泛型只能为Object或Object的子类的类型。
iv. 为泛型添加约束条件:泛型 extends 类
Collection(单列集合) API中说到:
Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。
一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。
即:Collection:是集合的顶层接口,它的子体系有重复的,有唯一的,有有序的,有无序的。
JDK 不提供此接口的任何直接 实现:它提供更具体的子接口(如 Set 和 List)实现。
此接口通常用来传递 collection,并在需要最大普遍性的地方操作这些 collection。
|– List(有序,可重复):保存元素加入的顺序(存储顺序和取出顺序一致),可以保存重复值
|– ArrayList:
线性数据结构(底层数据结构是数组)。查询快,增删慢。线程不安全,效率高。创建集合时可以指定集合的长度。
|– Vector:
线性数据结构(底层数据结构是数组)。查询快,增删慢。线程安全,效率低。功能与ArrayList完全一致。
|– LinkedList:
链表数据结构(底层数据结构是链表)。查询慢,增删快。线程不安全,效率高。创建集合时不能指定集合的长度。
|– Set(无序,唯一):不保存元素加入的顺序(存储顺序和取出顺序不一定一致),不能保存重复值
|– HashSet:
底层数据结构是哈希表(是一个元素为链表的数组)。集合中的元素根据哈希值进行排序。创建集合时可以指定集合的长度,长度不够时默认以75%的比例增加长度。
哈希表依赖两个方法:hashCode()和equals()
执行顺序:
首先判断hashCode()值是否相同
是:继续执行equals(),看其返回值
是true:说明元素重复,不添加
否false:就直接添加到集合
否:就直接添加到集合
最终:
自动生成hashCode()和equals()即可
|– LinkedHashSet:底层数据结构由链表和哈希表组成。由链表保证元素有序。由哈希表保证元素唯一。
|– TreeSet类:
底层数据结构是红黑树(是一个自平衡的二叉树)。集合中的元素以升序排序。创建集合不能指定集合的长度。
如何保证元素唯一性呢?
根据比较的返回值是否是0来决定
如何保证元素的排序呢?
两种方式
自然排序(元素具备比较性)
让元素所属的类实现Comparable接口
比较器排序(集合具备比较性)
让集合接收一个Comparator的实现类对象
Map(双列集合) A:Map集合的数据结构仅仅针对键有效,与值无关。
B: 以键值对(Key-Value)形式存储元素,键唯一,值可重复
API中说到:
将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
|– HashMap:
底层数据结构是哈希表。此实现不同步,线程不安全,效率高。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。
哈希表依赖两个方法:hashCode()和equals()
执行顺序:
首先判断hashCode()值是否相同
是:继续执行equals(),看其返回值
是true:说明元素重复,不添加
否false:就直接添加到集合
否:就直接添加到集合
最终:
自动生成hashCode()和equals()即可
|– LinkedHashMap:
Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现不同步,线程不安全。
哈希表保证元素唯一性。链表保证元素有序(存储和取出的顺序一致)
|– Hashtable:
底层数据结构是哈希表。线程安全,效率低。不允许使用 null 值和 null 键。
哈希表依赖两个方法:hashCode()和equals()
执行顺序:
首先判断hashCode()值是否相同
是:继续执行equals(),看其返回值
是true:说明元素重复,不添加
否false:就直接添加到集合
否:就直接添加到集合
最终:
自动生成hashCode()和equals()即可
|– TreeMap:
基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
此实现不同步,线程不安全。
如何保证元素唯一性呢?
根据比较的返回值是否是0来决定
如何保证元素的排序呢?
两种方式
自然排序(元素具备比较性)
让元素所属的类实现Comparable接口
比较器排序(集合具备比较性)
让集合接收一个Comparator的实现类对象
集合的选择 看需求。
是否是键值对象形式:
是:Map
键是否需要排序:
是:TreeMap
否:HashMap
不知道,就使用HashMap。
否:Collection
元素是否唯一:
是:Set
元素是否需要排序:
是:TreeSet
否:HashSet
不知道,就使用HashSet
否:List
要安全吗:
是:Vector(其实我们也不用它,了解多线程)
否:ArrayList或者LinkedList
增删多:LinkedList
查询多:ArrayList
不知道,就使用ArrayList
不知道,就使用ArrayList
集合的常见方法及遍历方式 Collection:
add()
remove()
contains()
iterator()
size()
遍历方式:
增强for
迭代器
|–List
get()
遍历方式:
普通for
|–Set
Map:
put()
remove()
containskey(),containsValue()
keySet()
get()
value()
entrySet()
size()
遍历方式:
根据键找值
根据键值对对象分别找键和值
掌握 ArrayList,、LinkedList、HashSet、HashMap,
存储字符串和自定义对象数据并遍历
集合的嵌套遍历
集合(Collection) 集合的由来 我们学习的是Java – 面向对象 – 操作很多对象 – 存储 – 容器(数组和StringBuffer) – 数组
而数组的长度固定,所以不适合做变化的需求,Java就提供了集合供我们使用。
我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储。
而要想存储多个对象,就不能是一个基本的变量,而应该是一个容器类型的变量,在我们目前所学过的知识里面,有哪些是容器类型的呢?
数组和StringBuffer。但是呢?StringBuffer的结果是一个字符串,不一定满足我们的要求,所以我们只能选择数组,这就是对象数组。
而对象数组又不能适应变化的需求,因为数组的长度是固定的,这个时候,为了适应变化的需求,Java就提供了集合类供我们使用。
集合和数组的区别 A:长度
数组长度固定
集合长度可变
B: 存储的数据类型
数组存储的数据可以是基本类型,也可以是引用类型,必须是同一种类型的元素。
集合存储的数据只能是引用类型, 可存储不同引用类型的元素。(例如:Student类型,Teacher类型)
C:元素内容
数组只能存储同一种类型的元素。
集合可存储不同引用类型的元素(其实集合一般存储的也是同一种类型),(例如:Student类型,Teacher类型)
集合的继承体系结构 由于需求不同,Java就提供了不同的集合类。这些集合类的*数据结构(数据的存储方式)*不同,但是它们都是要提供 存储、判断、获取 等功能。
我们把它们的共性不断的向上提取,最终就形成了集合的继承体系结构图。
API中说到:
Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素 。
一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。
即:Collection:是集合的顶层接口,它的子体系有重复的,有唯一的,有有序的,有无序的。
JDK 不提供此接口的任何直接 实现:它提供更具体的子接口(如 Set 和 List)实现。
此接口通常用来传递 collection,并在需要最大普遍性的地方操作这些 collection。
重点学习:
Collection
|–List
|–ArrayList
|–Vector
|–LinkedList
|–Set
|–HashSet
|–TreeSet
Collection功能 A:添加功能
1 2 3 4 boolean add (E e) :确保此 collection 包含指定的元素(可选操作)。 boolean add (Object obj) :添加一个元素。 boolean addAll (Collection<? extends E> c) :将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。 boolean addAll (Collection c) :添加一个集合的元素。
B:删除功能
1 2 3 4 void clear () :移除此 collection 中的所有元素(可选操作)。 boolean remove (Object o) :从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。 boolean removeAll (Collection<?> c) :移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。 boolean removeAll (Collection c) :移除一个集合的元素(只要有一个元素被移除了,就返回true 。)
C:判断功能
1 2 3 4 boolean contains (Object o) :如果此 collection 包含指定的元素,则返回 true 。 boolean containsAll (Collection<?> c) :如果此 collection 包含指定 collection 中的所有元素,则返回 true 。 boolean containsAll (Collection c) :判断集合中是否包含指定的集合元素(只有包含所有的元素,才叫包含,才会返回true ) boolean isEmpty () :如果此 collection 不包含元素,则返回 true 。
D:获取功能
1 2 3 4 Iterator<E> iterator () :返回在此 collection 的元素上进行迭代的Iterator(迭代器)。集合的专用遍历方式。(重点) E next () :返回迭代的下一个元素。抛出: NoSuchElementException - 没有元素可以迭代。 Object next () :获取元素,并移动到下一个位置。不要多次使用it.next()方法,因为每次使用都是访问一个对象。 boolean hasNext () :如果仍有元素可以迭代,则返回 true 。
E:长度功能
int size ():返回此 collection 中的元素数。
面试题:数组有没有length()方法呢?字符串有没有length()方法呢?集合有没有length()方法呢?
1 2 3 4 5 6 7 String str = "" ;String[] strArr = {}; ArrayList<String> list = new ArrayList <>(); str.length(); int a = strArr.length; list.size();
F:交集功能(了解)
1 2 boolean retainAll (Collection<?> c) :仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。 boolean retainAll (Collection c)
思考元素去哪了,返回的boolean又是什么意思呢? 解:假设有两个集合A,B。A对B做交集,最终的结果保存在A中,B不变。返回值表示的是A是否发生过改变,改变返回true。
G:把集合转数组(了解)
1 2 Object[] toArray():返回包含此 collection 中所有元素的数组。 <T> T[] toArray(T[] a):返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。
测试不带All的方法
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 public class CollectionDemo { public static void main (String[] args) { Collection<String> c = new ArrayList <String>(); System.out.println("add:" + c.add("hello" )); c.add("hello" ); c.add("world" ); c.add("java" ); System.out.println("c:" + c); System.out.println("remove:" + c.remove("hello" )); System.out.println("remove:" + c.remove("javaee" )); System.out.println("c:" + c); System.out.println("contains:" + c.contains("hello" )); System.out.println("contains:" + c.contains("android" )); System.out.println("isEmpty:" + c.isEmpty()); System.out.println("size:" + c.size()); } }
测试带All的方法
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 46 47 48 49 50 51 52 53 54 55 56 57 public class CollectionDemo { public static void main (String[] args) { Collection<String> c1 = new ArrayList <String>(); c1.add("abc1" ); c1.add("abc2" ); c1.add("abc3" ); c1.add("abc4" ); System.out.println("c1:" + c1); Collection<String> c2 = new ArrayList <String>(); c2.add("abc4" ); c2.add("abc5" ); c2.add("abc6" ); c2.add("abc7" ); System.out.println("c2:" + c2); System.out.println("addAll:" + c1.addAll(c2)); System.out.println("c1:" + c1); System.out.println("removeAll:" + c1.removeAll(c2)); System.out.println("c1:" + c1); c1.add("abc4" ); System.out.println("c1:" + c1); System.out.println("c2:" + c2); System.out.println("containsAll:" + c1.containsAll(c2)); System.out.println("c1:" + c1); System.out.println("c2:" + c2); System.out.println("retainAll:" + c1.retainAll(c2)); System.out.println("c1:" + c1); } }
Collection集合遍历 其实就是依次获取集合中的每一个元素。
A:把集合转数组(了解)
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 public class CollectionDemo { public static void main (String[] args) { Collection<Object> c = new ArrayList <Object>(); c.add("hello" ); c.add((Object) "world" ); c.add("java" ); Object[] objs = c.toArray(); for (int x = 0 ; x < objs.length; x++) { String s = (String) objs[x]; System.out.println(s + "---" + s.length()); } } }
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 public class StudentDemo { public static void main (String[] args) { Collection<Object> c = new ArrayList <Object>(); Student s1 = new Student ("林青霞" , 27 ); Student s2 = new Student ("风清扬" , 30 ); Student s3 = new Student ("令狐冲" , 33 ); Student s4 = new Student ("武鑫" , 25 ); Student s5 = new Student ("刘晓曲" , 22 ); c.add(s1); c.add((Object) s2); c.add(s3); c.add(s4); c.add(s5); Object[] objs = c.toArray(); for (int x = 0 ; x < objs.length; x++) { Student s = (Student) objs[x]; System.out.println(s.getName() + "---" + s.getAge()); } } } class Student { private String name; private int age; public Student () { super (); } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
B:迭代器(集合专用方式)
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 public class IteratorDemo { public static void main (String[] args) { Collection<Object> c = new ArrayList <Object>(); c.add("hello" ); c.add((Object) "world" ); c.add("java" ); Iterator<Object> it = c.iterator(); Object obj = it.next(); System.out.println(obj); while (it.hasNext()) { String s = (String) it.next(); System.out.println(s + "---" + s.length()); } } }
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 public class IteratorTest { public static void main (String[] args) { Collection<Object> c = new ArrayList <Object>(); Student s1 = new Student ("林青霞" , 27 ); Student s2 = new Student ("风清扬" , 30 ); Student s3 = new Student ("令狐冲" , 33 ); c.add(s1); c.add((Object) s2); c.add(s3); Iterator<Object> it = c.iterator(); while (it.hasNext()) { Student s = (Student) it.next(); System.out.println(s.getName() + "---" + s.getAge()); } for (Iterator<Object> it2 = c.iterator(); it2.hasNext();) { Student s = (Student) it2.next(); System.out.println(s.getName() + "---" + s.getAge()); } } } class Student { private String name; private int age; public Student () { super (); } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
迭代器 是集合获取元素的方式。
是依赖于集合而存在的。
迭代器的原理和源码。
a:为什么定义为了一个接口而不是实现类?
b:看了看迭代器的内部类实现。
迭代器使用图解和原理解析:
迭代器的源码:
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 public interface Interator { public abstract boolean hasNext () ; public abstract Object next () ; } public interface Iterable { Iterator<T> iterator () ; } public interface Collection extends Iterable { Iterator<E> iterator () ; } public interface List extends Collection { Iterator<E> iterator () ; } public class ArrayList implements List { public Iterator<E> iterator () { return new Itr (); } private class Itr implements Iterator <E> { public boolean hasNext () {} public E next () {} } } Collection c = new ArrayList ();c.add("hello" ); c.add("world" ); c.add("java" ); Iterator it = c.iterator(); while (it.hasNext()) { String s = (String)it.next(); System.out.println(s); }
Collection集合案例 遍历方式:迭代器
集合的操作步骤:
A:创建集合对象
B:创建元素对象
C:把元素添加到集合
D:遍历集合
A:存储字符串 并遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class CollectionDemo { public static void main (String[] args) { Collection<String> c = new ArrayList <String>(); c.add("hello" ); c.add("world" ); c.add("java" ); Iterator<String> it = c.iterator(); while (it.hasNext()) { String s = (String) it.next(); System.out.println(s); } } }
B:存储自定义对象 并遍历
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 46 47 48 49 50 51 52 53 54 public class StudentDemo { public static void main (String[] args) { Collection<Student> c = new ArrayList <Student>(); Student s1 = new Student ("貂蝉" , 25 ); Student s2 = new Student ("小乔" , 16 ); Student s3 = new Student ("黄月英" , 20 ); Student s4 = new Student (); s4.setName("大乔" ); s4.setAge(26 ); c.add(s1); c.add(s2); c.add(s3); c.add(s4); c.add(new Student ("孙尚香" , 18 )); Iterator<Student> it = c.iterator(); while (it.hasNext()) { Student s = (Student) it.next(); System.out.println(s.getName() + "---" + s.getAge()); } } } class Student { private String name; private int age; public Student () { } public Student (String name, int age) { this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
集合(List) List集合的特点 List:保存元素加入的顺序(存储顺序和取出顺序一致),可以保存重复值
|– ArrayList:线性数据结构(底层数据结构是数组)。查询快,增删慢。线程不安全,效率高。创建集合时可以指定集合的长度。
|– Vector:线性数据结构(底层数据结构是数组)。查询快,增删慢。线程安全,效率低。功能与ArrayList完全一致。
|– LinkedList:链表数据结构(底层数据结构是链表)。查询慢,增删快。线程不安全,效率高。创建集合时不能指定集合的长度。
Collection的子接口 有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。
与 set 不同,列表通常允许重复 的元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class ListDemo { public static void main (String[] args) { List<String> list = new ArrayList <String>(); list.add("hello" ); list.add("world" ); list.add("java" ); list.add("javaee" ); list.add("android" ); list.add("javaee" ); list.add("android" ); Iterator<String> it = list.iterator(); while (it.hasNext()) { String s = (String) it.next(); System.out.println(s); } } }
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 46 47 48 49 50 51 public class ListDemo { public static void main (String[] args) { List<Student> list = new ArrayList <Student>(); Student s1 = new Student ("白骨精" , 30 ); Student s2 = new Student ("蜘蛛精" , 40 ); Student s3 = new Student ("观音姐姐" , 22 ); list.add(s1); list.add(s2); list.add(s3); Iterator<Student> it = list.iterator(); while (it.hasNext()) { Student s = (Student) it.next(); System.out.println(s.getName() + "---" + s.getAge()); } } } class Student { private String name; private int age; public Student () { } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
List特有功能 将 E 看成Object
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 A:添加功能 void add (int index, E element) :在列表的指定位置插入指定元素(可选操作)。将当前处于该位置的元素(如果有的话)和所有后续元素向右移动(在其索引中加 1 )。 B:删除功能 E remove (int index) :移除列表中指定位置的元素(可选操作)。将所有的后续元素向左移动(将其索引减 1 )。返回从列表中移除的元素。 boolean remove (Object o) :从此列表中移除第一次出现的指定元素(如果存在)(可选操作)。如果列表不包含元素,则不更改列表。 C:获取功能 E get (int index) :返回:列表中指定位置的元素。 D:列表迭代器(List集合特有的迭代器) ListIterator<E> listIterator () :返回此列表元素的列表迭代器(按适当顺序)。 boolean hasPrevious () :返回: 如果以逆向遍历列表,列表迭代器有多个元素,则返回 true E previous () :返回: 列表中的上一个元素。 抛出: NoSuchElementException - 如果没有可迭代的上一个元素 E:修改功能 E set (int index, E element) :用指定元素替换列表中指定位置的元素(可选操作)。返回:以前在指定位置的元素。
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 public class ListDemo { public static void main (String[] args) { List<String> list = new ArrayList <String>(); list.add("hello" ); list.add("world" ); list.add("java" ); System.out.println("set:" + list.set(1 , "javaee" )); System.out.println("list:" + list); } }
List特有遍历功能 A:由size()和get()结合。
B:代码演示
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 public class ListDemo { public static void main (String[] args) { List<String> list = new ArrayList <String>(); list.add("hello" ); list.add("world" ); list.add("java" ); Iterator<String> it = list.iterator(); while (it.hasNext()) { String s = (String) it.next(); System.out.println(s); } for (int x = 0 ; x < list.size(); x++) { String s = (String) list.get(x); System.out.println(s); } } }
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 46 47 48 49 50 51 52 53 54 55 56 57 public class ListDemo { public static void main (String[] args) { List<Student> list = new ArrayList <Student>(); Student s1 = new Student ("林黛玉" , 18 ); Student s2 = new Student ("刘姥姥" , 88 ); Student s3 = new Student ("王熙凤" , 38 ); list.add(s1); list.add(s2); list.add(s3); Iterator<Student> it = list.iterator(); while (it.hasNext()) { Student s = (Student) it.next(); System.out.println(s.getName() + "---" + s.getAge()); } for (int x = 0 ; x < list.size(); x++) { Student s = (Student) list.get(x); System.out.println(s.getName() + "---" + s.getAge()); } } } class Student { private String name; private int age; public Student () { } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
列表迭代器特有功能 了解。可以逆向遍历,但是要先正向遍历,所以无意义,基本不使用。
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 public class ListIteratorDemo { public static void main (String[] args) { List<String> list = new ArrayList <String>(); list.add("hello" ); list.add("world" ); list.add("java" ); ListIterator<String> lit = list.listIterator(); while (lit.hasNext()) { String s = (String) lit.next(); System.out.println(s); } while (lit.hasPrevious()) { String s = (String) lit.previous(); System.out.println(s); } Iterator<String> it = list.iterator(); while (it.hasNext()) { String s = (String) it.next(); System.out.println(s); } } }
并发修改异常 ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
A:出现的现象
迭代器遍历集合过程中,通过集合对象修改集合元素。
B:原因
迭代器是依赖于集合的,而集合的改变迭代器并不知道。所以,迭代器遍历元素的过程中,通过集合是不能修改元素的。
C:解决方案
a:迭代器遍历,迭代器修改(ListIterator)
元素添加在刚才迭代的位置
b:集合遍历,集合修改(用for循环加上List集合 的size()和get()方法,Collection集合没有get()方法 )
元素添加在集合的末尾
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 public class ListIteratorDemo { public static void main (String[] args) { List<String> list = new ArrayList <String>(); list.add("hello" ); list.add("world" ); list.add("java" ); ListIterator<String> lit = list.listIterator(); while (lit.hasNext()) { String s = (String) lit.next(); if ("world" .equals(s)) { lit.add("javaee" ); } System.out.println(s); } for (int x = 0 ; x < list.size(); x++) { String s = (String) list.get(x); if ("world" .equals(s)) { list.add("javaee" ); } } System.out.println("list:" + list); } }
List的子类特点 ArrayList
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。
Vector
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
LinkedList
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。
到底使用谁呢?看需求?
分析:
要安全吗?
要:Vector(即使要,也不使用这个,后面再说)
不要:ArrayList或者LinkedList
查询多;ArrayList
增删多:LinkedList
什么都不知道,就用ArrayList。
List集合案例 遍历方式、迭代器、普通for
A:存储字符串并遍历
B:存储自定义对象并遍历
集合(List)的子类 List的子类特点 ArrayList:
线性数据结构(底层数据结构是数组)。查询快,增删慢。线程不安全,效率高。创建集合时可以指定集合的长度。
Vector:
线性数据结构(底层数据结构是数组)。查询快,增删慢。线程安全,效率低。功能与ArrayList完全一致。
LinkedList:
链表数据结构(底层数据结构是链表)。查询慢,增删快。线程不安全,效率高。创建集合时不能指定集合的长度。
案例:使用List的任何子类存储字符串或者存储自定义对象并遍历。
ArrayList A:没有特有功能需要学习
B:案例
a:ArrayList存储字符串并遍历
b:ArrayList存储自定义对象并遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class ArrayListDemo { public static void main (String[] args) { ArrayList<String> array = new ArrayList <String>(); array.add("hello" ); array.add("world" ); array.add("java" ); Iterator<String> it = array.iterator(); while (it.hasNext()) { String s = (String) it.next(); System.out.println(s); } for (int x = 0 ; x < array.size(); x++) { String s = (String) array.get(x); System.out.println(s); } } }
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 46 47 48 49 50 51 52 53 54 55 56 57 58 public class ArrayListDemo { public static void main (String[] args) { ArrayList<Student> array = new ArrayList <Student>(); Student s1 = new Student ("武松" , 30 ); Student s2 = new Student ("鲁智深" , 40 ); Student s3 = new Student ("林冲" , 36 ); Student s4 = new Student ("杨志" , 38 ); array.add(s1); array.add(s2); array.add(s3); array.add(s4); Iterator<Student> it = array.iterator(); while (it.hasNext()) { Student s = (Student) it.next(); System.out.println(s.getName() + "---" + s.getAge()); } for (int x = 0 ; x < array.size(); x++) { Student s = (Student) array.get(x); System.out.println(s.getName() + "---" + s.getAge()); } } } class Student { private String name; private int age; public Student () { } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
Vector A:有特有功能
1 2 3 4 5 6 7 8 a:添加 public void addElement (E obj) :将指定元素添加到此向量的末尾。 -- public boolean add (E e) b:获取 public E elementAt (int index) :返回指定索引处的组件。 -- public E get (int index) public Enumeration<E> elements () :返回此向量的组件的枚举。 -- iterator() boolean hasMoreElements () :测试此枚举是否包含更多的元素。 E nextElement () :如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class ArrayListDemo { public static void main (String[] args) { Vector<String> v = new Vector <String>(); v.addElement("hello" ); v.addElement("world" ); v.addElement("java" ); for (int x = 0 ; x < v.size(); x++) { String s = (String) v.elementAt(x); System.out.println(s); } Enumeration<String> en = v.elements(); while (en.hasMoreElements()) { String s = (String) en.nextElement(); System.out.println(s); } } }
B:案例
a:Vector存储字符串并遍历
b:Vector存储自定义对象并遍历
LinkedList A:有特有功能
1 2 3 4 5 6 7 8 9 10 11 a:添加 public void addFirst (E e) :将指定元素插入此列表的开头。 public void addLast (E e) :将指定元素添加到此列表的结尾。 b:获取 public E getFirst () :返回此列表的第一个元素。 public E getLast () :返回此列表的最后一个元素。 c:删除 public E removeFirst () :移除并返回此列表的第一个元素。 public E removeLast () :移除并返回此列表的最后一个元素。
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 public class LinkedListDemo { public static void main (String[] args) { LinkedList<String> link = new LinkedList <String>(); link.add("hello" ); link.add("world" ); link.add("java" ); System.out.println("removeFirst:" + link.removeFirst()); System.out.println("removeLast:" + link.removeLast()); System.out.println("link:" + link); } }
B:案例
a:LinkedList存储字符串并遍历
b:LinkedList存储自定义对象并遍历
案例 A: ArrayList去除集合中的多个字符串的重复元素(如果字符串的内容相同,即为重复元素)
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 46 47 48 49 public class ArrayListDemo { public static void main (String[] args) { ArrayList<String> array = new ArrayList <String>(); array.add("hello" ); array.add("world" ); array.add("java" ); array.add("world" ); array.add("java" ); array.add("world" ); array.add("world" ); array.add("world" ); array.add("world" ); array.add("java" ); array.add("world" ); ArrayList<String> newArray = new ArrayList <String>(); Iterator<String> it = array.iterator(); while (it.hasNext()) { String s = (String) it.next(); if (!newArray.contains(s)) { newArray.add(s); } } for (int x = 0 ; x < newArray.size(); x++) { String s = (String) newArray.get(x); System.out.println(s); } } }
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 public class ArrayListDemo { public static void main (String[] args) { ArrayList<String> array = new ArrayList <String>(); array.add("hello" ); array.add("world" ); array.add("java" ); array.add("world" ); array.add("java" ); array.add("world" ); array.add("world" ); array.add("world" ); array.add("world" ); array.add("java" ); array.add("world" ); for (int x = 0 ; x < array.size() - 1 ; x++) { for (int y = x + 1 ; y < array.size(); y++) { if (array.get(x).equals(array.get(y))) { array.remove(y); y--; } } } Iterator<String> it = array.iterator(); while (it.hasNext()) { String s = (String) it.next(); System.out.println(s); } } }
B: ArrayList去除集合中的自定义对象的重复元素(如果自定义对象的成员变量值都相同,即为重复元素 )
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 public class ArrayListDemo { public static void main (String[] args) { ArrayList<Student> array = new ArrayList <Student>(); Student s1 = new Student ("林青霞" , 27 ); Student s2 = new Student ("林志玲" , 40 ); Student s3 = new Student ("凤姐" , 35 ); Student s4 = new Student ("芙蓉姐姐" , 18 ); Student s5 = new Student ("翠花" , 16 ); Student s6 = new Student ("林青霞" , 27 ); Student s7 = new Student ("林青霞" , 18 ); array.add(s1); array.add(s2); array.add(s3); array.add(s4); array.add(s5); array.add(s6); array.add(s7); ArrayList<Student> newArray = new ArrayList <Student>(); Iterator<Student> it = array.iterator(); while (it.hasNext()) { Student s = (Student) it.next(); if (!newArray.contains(s)) { newArray.add(s); } } for (int x = 0 ; x < newArray.size(); x++) { Student s = (Student) newArray.get(x); System.out.println(s.getName() + "---" + s.getAge()); } } } class Student { private String name; private int age; public Student () { } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } @Override public boolean equals (Object obj) { if (this == obj) return true ; if (obj == null ) return false ; if (getClass() != obj.getClass()) return false ; Student other = (Student) obj; if (age != other.age) return false ; if (name == null ) { if (other.name != null ) return false ; } else if (!name.equals(other.name)) return false ; return true ; } }
C:用LinkedList模拟 一个栈数据结构的集合类 ,并测试。
你要定义一个集合类,只不过内部可以使用LinkedList来实现。
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 public class MyStackListDemo { public static void main (String[] args) { MyStackList msl = new MyStackList (); msl.add("hello" ); msl.add("world" ); msl.add("java" ); while (!msl.isEmpty()) { System.out.println(msl.get()); } } } class MyStackList { private LinkedList<Object> link; public MyStackList () { link = new LinkedList <Object>(); } public void add (Object obj) { link.addFirst(obj); } public Object get () { return link.removeFirst(); } public boolean isEmpty () { return link.isEmpty(); } }
Generic泛型 泛型概述 是一种把明确类型 的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。参数化类型,把类型当作参数一样的传递。
格式 <数据类型>
注意:该数据类型只能是引用类型。
好处 A:把运行时期的问题提前到了编译期间
B:避免了强制类型转换
C:优化了程序设计,解决了黄色警告线问题,让程序更安全
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 public class GenericDemo { public static void main (String[] args) { ArrayList<String> array = new ArrayList <String>(); array.add("hello" ); array.add("world" ); array.add("java" ); Iterator<String> it = array.iterator(); while (it.hasNext()) { String s = it.next(); System.out.println(s); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class GenericDemo { public static void main (String[] args) { ArrayList<String> array = new ArrayList <String>(); array.add("hello" ); array.add("world" ); array.add("java" ); Iterator<String> it = array.iterator(); while (it.hasNext()) { String s = it.next(); System.out.println(s); } for (int x = 0 ; x < array.size(); x++) { String s = array.get(x); System.out.println(s); } } }
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 public class GenericDemo { public static void main (String[] args) { ArrayList<Student> array = new ArrayList <Student>(); Student s1 = new Student ("曹操" , 40 ); Student s2 = new Student ("蒋干" , 30 ); Student s3 = new Student ("诸葛亮" , 26 ); array.add(s1); array.add(s2); array.add(s3); Iterator<Student> it = array.iterator(); while (it.hasNext()) { Student s = it.next(); System.out.println(s.getName() + "---" + s.getAge()); } for (int x = 0 ; x < array.size(); x++) { Student s = array.get(x); System.out.println(s.getName() + "---" + s.getAge()); } } } class Student { private String name; private int age; public Student () { } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
泛型的前世今生 A:泛型的由来
早期的时候,我们使用Object来代表任意的类型。
向上转型是没有任何问题的,但是在向下转型的时候其实隐含了类型转换的问题。
也就是说这样的程序其实并不是安全的。所以Java在JDK5后引入了泛型,提高程序的安全性。
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 public class ObjectToolDemo { public static void main (String[] args) { ObjectTool ot = new ObjectTool (); ot.setObj(new Integer (27 )); Integer i = (Integer) ot.getObj(); System.out.println("年龄是:" + i); ot.setObj(new String ("林青霞" )); String s = (String) ot.getObj(); System.out.println("姓名是:" + s); ot.setObj(new Integer (30 )); String ss = (String) ot.getObj(); System.out.println("姓名是:" + ss); } } class ObjectTool { private Object obj; public Object getObj () { return obj; } public void setObj (Object obj) { this .obj = obj; } }
B:泛型类:把泛型定义在类上
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 public class ObjectToolDemo { public static void main (String[] args) { ObjectTool<String> ot = new ObjectTool <String>(); ot.setObj(new String ("林青霞" )); String s = ot.getObj(); System.out.println("姓名是:" + s); ObjectTool<Integer> ot2 = new ObjectTool <Integer>(); ot2.setObj(new Integer (27 )); Integer i = ot2.getObj(); System.out.println("年龄是:" + i); } } class ObjectTool <T> { private T obj; public T getObj () { return obj; } public void setObj (T obj) { this .obj = obj; } }
C:泛型方法:把泛型定义在方法上
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 46 47 48 49 50 51 public class ObjectToolDemo { public static void main (String[] args) { ObjectTool ot = new ObjectTool (); ot.show("hello" ); ot.show(100 ); ot.show(true ); ObjectTool<String> ot1 = new ObjectTool <String>(); ot1.show("hello" ); ObjectTool<Integer> ot2 = new ObjectTool <Integer>(); ot2.show(100 ); ObjectTool<Boolean> ot3 = new ObjectTool <Boolean>(); ot3.show(true ); ObjectTool2 ot4 = new ObjectTool2 (); ot4.show("hello" ); ot4.show(100 ); ot4.show(true ); } } class ObjectTool <T> { public void show (T t) { System.out.println(t); } } class ObjectTool2 { public <T> void show (T t) { System.out.println(t); } }
D:泛型接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 interface Inter <T> { public abstract void show (T t) ; } class InterImpl <T> implements Inter <T> { public void show (T t) { System.out.println(t); } } public class InterDemo { public static void main (String[] args) { Inter<String> i = new InterImpl <String>(); i.show("hello" ); Inter<Integer> ii = new InterImpl <Integer>(); ii.show(100 ); } }
E:泛型高级(通配符)
? :任意类型,如果没有明确,那么就是Object以及任意的Java类了
? extends E :上边界(上界),向下限定,E及其子类
? super E :下边界(下界),向上限定,E极其父类
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 public class GenericDemo { public static void main (String[] args) { Collection<Object> c1 = new ArrayList <Object>(); Collection<?> c5 = new ArrayList <Object>(); Collection<?> c6 = new ArrayList <Animal>(); Collection<?> c7 = new ArrayList <Dog>(); Collection<?> c8 = new ArrayList <Cat>(); Collection<? extends Animal > c10 = new ArrayList <Animal>(); Collection<? extends Animal > c11 = new ArrayList <Dog>(); Collection<? extends Animal > c12 = new ArrayList <Cat>(); Collection<? super Animal> c13 = new ArrayList <Object>(); Collection<? super Animal> c14 = new ArrayList <Animal>(); } } class Animal {} class Dog extends Animal {} class Cat extends Animal {}
应用 看API,如果类,接口,抽象类后面跟的有<E>就说明要使用泛型。一般来说就是在集合中使用。
JDK5News JDK5的新特性:自动拆装箱,泛型,增强for,静态导入,可变参数,枚举
一、增强for循环(掌握)
1. 是for循环的一种
2. 格式:
for(元素的数据类型 变量名 : 数组或者Collection集合的对象) {
使用该变量即可,该变量其实就是数组或者集合中的元素。
}
3. 好处:
简化了数组和集合的遍历
4. 弊端
增强for循环的目标不能为null 。建议在使用前,先判断是否为null。
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 46 47 48 49 50 51 public class ForDemo { public static void main (String[] args) { int [] arr = { 1 , 2 , 3 , 4 , 5 }; for (int x = 0 ; x < arr.length; x++) { System.out.println(arr[x]); } for (int x : arr) { System.out.println(x); } String[] strArray = { "林青霞" , "风清扬" , "东方不败" , "刘意" }; for (String s : strArray) { System.out.println(s); } ArrayList<String> array = new ArrayList <String>(); array.add("hello" ); array.add("world" ); array.add("java" ); for (String s : array) { System.out.println(s); } } }
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 public class ArrayListDemo { public static void main (String[] args) { ArrayList<String> array = new ArrayList <String>(); array.add("hello" ); array.add("world" ); array.add("java" ); Iterator<String> it = array.iterator(); while (it.hasNext()) { String s = it.next(); System.out.println(s); } for (int x = 0 ; x < array.size(); x++) { String s = array.get(x); System.out.println(s); } for (String s : array) { System.out.println(s); } } }
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 public class ArrayListDemo2 { public static void main (String[] args) { ArrayList<Student> array = new ArrayList <Student>(); Student s1 = new Student ("林青霞" , 27 ); Student s2 = new Student ("貂蝉" , 22 ); Student s3 = new Student ("杨玉环" , 24 ); Student s4 = new Student ("西施" , 21 ); Student s5 = new Student ("王昭君" , 23 ); array.add(s1); array.add(s2); array.add(s3); array.add(s4); array.add(s5); Iterator<Student> it = array.iterator(); while (it.hasNext()) { Student s = it.next(); System.out.println(s.getName() + "---" + s.getAge()); } for (int x = 0 ; x < array.size(); x++) { Student s = array.get(x); System.out.println(s.getName() + "---" + s.getAge()); } for (Student s : array) { System.out.println(s.getName() + "---" + s.getAge()); } } } class Student { private String name; private int age; public Student () { super (); } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
二、静态导入(了解)
1. 可以导入到方法级别的导入
2. 格式:
import static 包名….类名.方法名;
3. 注意事项:
A:方法必须是静态的
B:如果多个类下有同名的静态方法,就不好区分了,必须加前缀。所以一般我们并不使用静态导入,但是一定要能够看懂。
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 import static java.lang.Math.max;import static java.lang.Math.pow;public class StaticImportDemo { public static void main (String[] args) { System.out.println(java.lang.Math.abs(-100 )); System.out.println(java.lang.Math.pow(2 , 3 )); System.out.println(java.lang.Math.max(20 , 30 )); System.out.println(Math.abs(-100 )); System.out.println(Math.pow(2 , 3 )); System.out.println(Math.max(20 , 30 )); System.out.println(java.lang.Math.abs(-100 )); System.out.println(pow(2 , 3 )); System.out.println(max(20 , 30 )); } public static void abs (String s) { System.out.println(s); } }
三、可变参数(掌握)
1. 如果我们在写方法的时候,参数个数不明确 ,就应该定义可变参数。
2. 格式:
修饰符 返回值类型 方法名(数据类型… 变量名) {}
注意:
A:该变量名其实是一个数组名
B:如果一个方法有多个参数,并且有可变参数,可变参数必须在最后
3. Arrays工具类的一个方法
asList() : 把数组转成集合 。
注意:这个集合的长度不能改变 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class ArgsDemo { public static void main (String[] args) { int result = sum(10 , 20 , 30 , 40 ); System.out.println("result:" + result); result = sum(10 , 20 , 30 , 40 , 50 ); System.out.println("result:" + result); } public static int sum (int b, int ... a) { System.out.println(a); int s = b; for (int x : a) { s += x; } return s; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class ArraysDemo { public static void main (String[] args) { List<String> list = Arrays.asList("hello" , "world" , "java" ); list.set(1 , "javaee" ); for (String s : list) { System.out.println(s); } } }
List_Son_test 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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 public class ArrayListDemo { public static void main (String[] args) { ArrayList<ArrayList<Student>> bigArrayList = new ArrayList <ArrayList<Student>>(); ArrayList<Student> firstArrayList = new ArrayList <Student>(); Student s1 = new Student ("唐僧" , 30 ); Student s2 = new Student ("孙悟空" , 29 ); Student s3 = new Student ("猪八戒" , 28 ); Student s4 = new Student ("沙僧" , 27 ); Student s5 = new Student ("白龙马" , 26 ); firstArrayList.add(s1); firstArrayList.add(s2); firstArrayList.add(s3); firstArrayList.add(s4); firstArrayList.add(s5); bigArrayList.add(firstArrayList); ArrayList<Student> secondArrayList = new ArrayList <Student>(); Student s11 = new Student ("诸葛亮" , 30 ); Student s22 = new Student ("司马懿" , 28 ); Student s33 = new Student ("周瑜" , 26 ); secondArrayList.add(s11); secondArrayList.add(s22); secondArrayList.add(s33); bigArrayList.add(secondArrayList); ArrayList<Student> thirdArrayList = new ArrayList <Student>(); Student s111 = new Student ("宋江" , 40 ); Student s222 = new Student ("吴用" , 35 ); Student s333 = new Student ("高俅" , 30 ); Student s444 = new Student ("李师师" , 22 ); thirdArrayList.add(s111); thirdArrayList.add(s222); thirdArrayList.add(s333); thirdArrayList.add(s444); bigArrayList.add(thirdArrayList); for (ArrayList<Student> array : bigArrayList) { for (Student s : array) { System.out.println(s.getName() + "---" + s.getAge()); } } } } class Student { private String name; private int age; public Student () { super (); } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
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 46 47 public class RandomDemo { public static void main (String[] args) { Random r = new Random (); ArrayList<Integer> array = new ArrayList <Integer>(); int count = 0 ; while (count < 10 ) { int number = r.nextInt(20 ) + 1 ; if (!array.contains(number)) { array.add(number); count++; } } for (Integer i : array) { System.out.println(i); } } }
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 public class ArrayListDemo { public static void main (String[] args) { Scanner sc = new Scanner (System.in); ArrayList<Integer> array = new ArrayList <Integer>(); while (true ) { System.out.println("请输入数据:" ); int number = sc.nextInt(); if (number != 0 ) { array.add(number); } else { break ; } } Integer[] i = new Integer [array.size()]; array.toArray(i); Arrays.sort(i); System.out.println("数组是:" + arrayToString(i) + "最大值是:" + i[i.length - 1 ]); } public static String arrayToString (Integer[] i) { StringBuilder sb = new StringBuilder (); sb.append("[" ); for (int x = 0 ; x < i.length; x++) { if (x == i.length - 1 ) { sb.append(i[x]); } else { sb.append(i[x]).append(", " ); } } sb.append("]" ); return sb.toString(); } }
集合(Set) Set集合特点 Set:不保存元素加入的顺序(存储顺序和取出顺序不一定一致),不能保存重复值
|– HashSet:底层数据结构是哈希表(是一个元素为链表的数组)。集合中的元素根据哈希值进行排序(好像不是)。创建集合时可以指定集合的长度,长度不够时默认以75%的比例增加长度。
|– TreeSet类:底层数据结构是红黑树(是一个自平衡的二叉树)。集合中的元素按照某种规则进行排序 。创建集合不能指定集合的长度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class SetDemo { public static void main (String[] args) { Set<String> set = new HashSet <String>(); set.add("hello" ); set.add("java" ); set.add("world" ); set.add("java" ); set.add("world" ); for (String s : set) { System.out.println(s); } } }
HashSet集合 它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素 。
A:底层数据结构是哈希表 (是一个元素为链表的数组)
B:哈希表底层依赖两个方法:hashCode()和equals()
执行顺序:
首先比较哈希值是否相同
相同:继续执行equals()方法
返回true:元素重复了,不添加
返回false:直接把元素添加到集合
不同:就直接把元素添加到集合
C:如何保证元素唯一性的呢?
由hashCode()和equals()保证的
D:开发的时候,代码非常的简单,自动生成即可。
E:HashSet存储字符串并遍历
F:HashSet存储自定义对象并遍历(对象的成员变量值相同即为同一个元素)
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 public class HashSetDemo { public static void main (String[] args) { HashSet<String> hs = new HashSet <String>(); hs.add("hello" ); hs.add("world" ); hs.add("java" ); hs.add("world" ); for (String s : hs) { System.out.println(s); } HashCodeDemo.test(); } } class HashCodeDemo { public static void test () { System.out.println("hello" .hashCode()); System.out.println("hello" .hashCode()); System.out.println("world" .hashCode()); } }
HashSet集合的add()方法的源码解析:(JDK版本不同,源码可能会不同)
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 interface Collection { ... } interface Set extends Collection { ... } class HashSet implements Set { private static final Object PRESENT = new Object (); private transient HashMap<E,Object> map; public HashSet () { map = new HashMap <>(); } public boolean add (E e) { return map.put(e, PRESENT)==null ; } } class HashMap implements Map { public V put (K key, V value) { if (table == EMPTY_TABLE) { inflateTable(threshold); } if (key == null ) return putForNullKey(value); int hash = hash(key); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null ; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this ); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null ; } transient int hashSeed = 0 ; final int hash (Object k) { int h = hashSeed; if (0 != h && k instanceof String) { return sun.misc.Hashing.stringHash32((String) k); } h ^= k.hashCode(); h ^= (h >>> 20 ) ^ (h >>> 12 ); return h ^ (h >>> 7 ) ^ (h >>> 4 ); } } hs.add("hello" ); hs.add("world" ); hs.add("java" ); hs.add("world" );
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 public class HashSetDemo2 { public static void main (String[] args) { HashSet<Student> hs = new HashSet <Student>(); Student s1 = new Student ("林青霞" , 27 ); Student s2 = new Student ("柳岩" , 22 ); Student s3 = new Student ("王祖贤" , 30 ); Student s4 = new Student ("林青霞" , 27 ); Student s5 = new Student ("林青霞" , 20 ); Student s6 = new Student ("范冰冰" , 22 ); hs.add(s1); hs.add(s2); hs.add(s3); hs.add(s4); hs.add(s5); hs.add(s6); for (Student s : hs) { System.out.println(s.getName() + "---" + s.getAge()); } } } class Student { private String name; private int age; public Student () { } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class LinkedHashSetDemo { public static void main (String[] args) { LinkedHashSet<String> hs = new LinkedHashSet <String>(); hs.add("hello" ); hs.add("world" ); hs.add("java" ); hs.add("world" ); hs.add("java" ); for (String s : hs) { System.out.println(s); } } }
TreeSet集合 使用元素的自然顺序 对元素进行排序,或者根据创建集合时提供的 Comparator 进行排序,具体取决于使用的构造方法(详情看API:TreeSet的构造方法)。总之,元素或集合必须要有比较性 。
A:底层数据结构是红黑树(是一个自平衡的二叉树)
B:保证元素的排序方式
a:自然排序 (元素具备比较性)
让存储的元素所属的类 实现自然排序接口:Comparable接口
b:比较器排序 (集合具备比较性)
让集合构造方法接收Comparator的实现类对象
C:把代码看一遍即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class TreeSetDemo { public static void main (String[] args) { TreeSet<Integer> ts = new TreeSet <Integer>(); ts.add(20 ); ts.add(18 ); ts.add(23 ); ts.add(22 ); ts.add(17 ); ts.add(24 ); ts.add(19 ); ts.add(18 ); ts.add(24 ); for (Integer i : ts) { System.out.println(i); } } }
TreeSet的add()方法的源码解析:(JDK版本不同,源码可能会不同)
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 interface Collection {...}interface Set extends Collection {...}interface NavigableMap {} class TreeMap implements NavigableMap { public V put (K key, V value) { Entry<K,V> t = root; if (t == null ) { compare(key, key); root = new Entry <>(key, value, null ); size = 1 ; modCount++; return null ; } int cmp; Entry<K,V> parent; Comparator<? super K> cpr = comparator; if (cpr != null ) { do { parent = t; cmp = cpr.compare(key, t.key); if (cmp < 0 ) t = t.left; else if (cmp > 0 ) t = t.right; else return t.setValue(value); } while (t != null ); } else { if (key == null ) throw new NullPointerException (); Comparable<? super K> k = (Comparable<? super K>) key; do { parent = t; cmp = k.compareTo(t.key); if (cmp < 0 ) t = t.left; else if (cmp > 0 ) t = t.right; else return t.setValue(value); } while (t != null ); } Entry<K,V> e = new Entry <>(key, value, parent); if (cmp < 0 ) parent.left = e; else parent.right = e; fixAfterInsertion(e); size++; modCount++; return null ; } } class TreeSet implements Set { private transient NavigableMap<E,Object> m; public TreeSet () { this (new TreeMap <E,Object>()); } public boolean add (E e) { return m.put(e, PRESENT)==null ; } } 真正的比较是依赖于元素的compareTo()方法,而这个方法是定义在 Comparable里面的。 所以,你要想重写该方法,就必须实现 Comparable接口。这个接口表示的就是自然排序。
TreeSet存储元素自然排序和唯一(元素不重复)的图解:
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 public class TreeSetDemo2 { public static void main (String[] args) { TreeSet<Student> ts = new TreeSet <Student>(); Student s1 = new Student ("l__" , 27 ); Student s2 = new Student ("z__" , 29 ); Student s3 = new Student ("w__" , 23 ); Student s4 = new Student ("l__" , 27 ); Student s5 = new Student ("l__" , 22 ); Student s6 = new Student ("w__" , 40 ); Student s7 = new Student ("f__" , 22 ); Student s8 = new Student ("G__" , 22 ); ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); ts.add(s7); ts.add(s8); for (Student s : ts) { System.out.println(s.getName() + "---" + s.getAge()); } } } class Student implements Comparable <Student> { private String name; private int age; public Student () { } public Student (String name, int age) { super (); this .name = name; this .age = age; } public int compareTo (Student s) { int num = this .age - s.age; int num2 = num == 0 ? this .name.compareTo(s.name) : num; return num2; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 public class TreeSetDemo { public static void main (String[] args) { TreeSet<Student> ts = new TreeSet <Student>(); Student s1 = new Student ("l" , 27 ); Student s2 = new Student ("zhang" , 29 ); Student s3 = new Student ("wangl" , 23 ); Student s4 = new Student ("linqing" , 29 ); Student s5 = new Student ("linqing" , 22 ); Student s6 = new Student ("liu" , 22 ); Student s7 = new Student ("wuqilong" , 40 ); Student s8 = new Student ("linqingxia" , 29 ); ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); ts.add(s7); ts.add(s8); for (Student s : ts) { System.out.println(s.getName() + "---" + s.getAge()); } } } class Student implements Comparable <Student> { private String name; private int age; public Student () { } public Student (String name, int age) { super (); this .name = name; this .age = age; } public int compareTo (Student s) { int num = this .name.length() - s.name.length(); int num2 = num == 0 ? this .name.compareTo(s.name) : num; int num3 = num2 == 0 ? this .age - s.age : num2; return num3; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
如果很多地方使用Student类,要求的排序方式又不同,那就没办法实现了。这时就需要使用比较器排序,看下面的例子
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 public class TreeSetDemo { public static void main (String[] args) { TreeSet<Student> ts = new TreeSet <Student>(new Comparator <Student>() { @Override public int compare (Student s1, Student s2) { int num = s1.getName().length() - s2.getName().length(); int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2; return num3; } }); Student s1 = new Student ("l" , 27 ); Student s2 = new Student ("zhang" , 29 ); Student s3 = new Student ("wangl" , 23 ); Student s4 = new Student ("linqing" , 29 ); Student s5 = new Student ("linqing" , 22 ); Student s6 = new Student ("liu" , 22 ); Student s7 = new Student ("wuqilong" , 40 ); Student s8 = new Student ("linqingxia" , 29 ); ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s4); ts.add(s5); ts.add(s6); ts.add(s7); ts.add(s8); for (Student s : ts) { System.out.println(s.getName() + "---" + s.getAge()); } } } class MyComparator implements Comparator <Student> { public int compare (Student s1, Student s2) { int num = s1.getName().length() - s2.getName().length(); int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2; return num3; } } class Student { private String name; private int age; public Student () { } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
案例 A:获取无重复的随机数
B:键盘录入学生按照总分从高到底输出
案例A:
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 public class HashSetDemo { public static void main (String[] args) { Random r = new Random (); HashSet<Integer> ts = new HashSet <Integer>(); while (ts.size() < 10 ) { int num = r.nextInt(20 ) + 1 ; ts.add(num); } for (Integer i : ts) { System.out.println(i); } System.out.println(ts); } }
案例B:
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 public class TreeSetDemo { public static void main (String[] args) { TreeSet<Student> ts = new TreeSet <Student>(new Comparator <Student>() { @Override public int compare (Student s1, Student s2) { int num = s2.getSum() - s1.getSum(); int num2 = num == 0 ? s1.getChinese() - s2.getChinese() : num; int num3 = num2 == 0 ? s1.getMath() - s2.getMath() : num2; int num4 = num3 == 0 ? s1.getEnglish() - s2.getEnglish() : num3; int num5 = num4 == 0 ? s1.getName().compareTo(s2.getName()) : num4; return num5; } }); System.out.println("学生信息录入开始" ); for (int x = 1 ; x <= 5 ; x++) { Scanner sc = new Scanner (System.in); System.out.println("请输入第" + x + "个学生的姓名:" ); String name = sc.nextLine(); System.out.println("请输入第" + x + "个学生的语文成绩:" ); String chineseString = sc.nextLine(); System.out.println("请输入第" + x + "个学生的数学成绩:" ); String mathString = sc.nextLine(); System.out.println("请输入第" + x + "个学生的英语成绩:" ); String englishString = sc.nextLine(); Student s = new Student (); s.setName(name); s.setChinese(Integer.parseInt(chineseString)); s.setMath(Integer.parseInt(mathString)); s.setEnglish(Integer.parseInt(englishString)); ts.add(s); } System.out.println("学生信息录入完毕" ); System.out.println("学习信息从高到低排序如下:" ); System.out.println("姓名\t语文成绩\t数学成绩\t英语成绩\t总分" ); for (Student s : ts) { System.out.println(s.getName() + "\t" + s.getChinese() + "\t" + s.getMath() + "\t" + s.getEnglish() + "\t" + (s.getChinese() + s.getMath() + s.getEnglish())); } } } class Student { private String name; private int chinese; private int math; private int english; public Student () { } public Student (String name, int chinese, int math, int english) { super (); this .name = name; this .chinese = chinese; this .math = math; this .english = english; } public int getSum () { return chinese + math + english; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getChinese () { return chinese; } public void setChinese (int chinese) { this .chinese = chinese; } public int getMath () { return math; } public void setMath (int math) { this .math = math; } public int getEnglish () { return english; } public void setEnglish (int english) { this .english = english; } }
集合(Map) 介绍 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
Map和Collection的区别 A:Map 存储的是键值对形式的元素,键唯一,值可以重复。
B:Collection 存储的是单独出现的元素,子接口Set元素唯一,子接口List元素可重复。
Map接口功能概述 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 A:添加功能 V put (K key, V value) :将指定的值与此映射中的指定键关联(可选操作)。返回:以前与 key 关联的值。如果没有针对 key 的映射关系,则返回 null 。 (如果该实现支持 null 值,则返回 null 也可能表示此映射以前将 null 与 key 关联)。 void putAll (Map<? extends K,? extends V> m) :从指定映射中将所有映射关系复制到此映射中(可选操作)。 B:删除功能 void clear () :从此映射中移除所有映射关系(可选操作)。此调用返回后,该映射将为空。 V remove (Object key) :如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。返回:以前与 key 关联的值;如果没有 key 的映射关系,则返回 null 。 C:判断功能 boolean containsKey (Object key) :如果此映射包含指定键的映射关系,则返回 true 。 boolean containsValue (Object value) :如果此映射将一个或多个键映射到指定值,则返回 true 。 boolean isEmpty () :如果此映射未包含键-值映射关系,则返回 true 。 D:获取功能 Set<Map.Entry<K,V>> entrySet():返回此映射中包含的映射关系的 Set 视图。 V get (Object key) :返回指定键所映射的值; Set<K> keySet () :返回此映射中包含的键的 Set 视图。 Collection<V> values () :返回此映射中包含的值的 Collection 视图。 E:长度功能 int size () :返回此映射中的键-值映射关系数。
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 public class MapDemo { public static void main (String[] args) { Map<String, String> map = new HashMap <String, String>(); map.put("邓超" , "孙俪" ); map.put("黄晓明" , "杨颖" ); map.put("周杰伦" , "蔡依林" ); map.put("刘恺威" , "杨幂" ); System.out.println("containsKey:" + map.containsKey("黄晓明" )); System.out.println("containsKey:" + map.containsKey("黄晓波" )); System.out.println("isEmpty:" + map.isEmpty()); System.out.println("size:" + map.size()); System.out.println("map:" + map); } }
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 public class MapDemo2 { public static void main (String[] args) { Map<String, String> map = new HashMap <String, String>(); map.put("邓超" , "孙俪" ); map.put("黄晓明" , "杨颖" ); map.put("周杰伦" , "蔡依林" ); map.put("刘恺威" , "杨幂" ); System.out.println("get:" + map.get("周杰伦" )); System.out.println("get:" + map.get("周杰" )); Set<String> set = map.keySet(); for (String key : set) { System.out.println(key); } Collection<String> con = map.values(); for (String value : con) { System.out.println(value); } } }
Map集合遍历 A:键找值
a:获取所有键的集合
b:遍历键的集合,获取每一个键
c:根据键到集合中去找值
B:键值对对象找键和值
a:获取所有的键值对对象的集合
b:遍历键值对对象的集合,获取每一个键值对对象
c:根据键值对对象去获取键和值
代码体现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Map<String,String> hm = new HashMap <String,String>(); hm.put("杨过" , "小龙女" ); hm.put("郭靖" , "黄蓉" ); hm.put("杨康" , "穆念慈" ); hm.put("陈玄风" , "梅超风" ); Set<String> set = hm.keySet(); for (String key : set) { String value = hm.get(key); System.out.println(key+"---" +value); } Set<Map.Entry<String,String>> set2 = hm.entrySet(); for (Map.Entry<String,String> me : set2) { String key = me.getKey(); String value = me.getValue(); System.out.println(key+"---" +value); }
HashMap集合练习 A:HashMap<String,String>
B:HashMap<Integer,String>
C:HashMap<String,Student>
D:HashMap<Student,String>
E:LinkedHashMap<String,String> 保存元素加入的顺序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class HashMapDemo { public static void main (String[] args) { HashMap<String, String> hm = new HashMap <String, String>(); hm.put("it001" , "马云" ); hm.put("it003" , "马化腾" ); hm.put("it004" , "乔布斯" ); hm.put("it005" , "张朝阳" ); hm.put("it002" , "裘伯君" ); hm.put("it001" , "比尔盖茨" ); Set<String> set = hm.keySet(); for (String key : set) { String value = hm.get(key); System.out.println(key + "---" + value); } } }
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 public class HashMapDemo2 { public static void main (String[] args) { HashMap<Integer, String> hm = new HashMap <Integer, String>(); hm.put(27 , "林青霞" ); hm.put(30 , "风清扬" ); hm.put(29 , "林青霞" ); hm.put(28 , "刘意" ); hm.put(28 , "刘意" ); hm.put(28 , "刘亦菲" ); Set<Integer> set = hm.keySet(); for (Integer key : set) { String value = hm.get(key); System.out.println(key + "---" + value); } } }
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 public class HashMapDemo3 { public static void main (String[] args) { HashMap<String, Student> hm = new HashMap <String, Student>(); Student s1 = new Student ("周星驰" , 58 ); Student s2 = new Student ("刘德华" , 55 ); Student s3 = new Student ("梁朝伟" , 54 ); Student s4 = new Student ("刘嘉玲" , 50 ); Student s5 = new Student ("刘嘉玲" , 50 ); hm.put("9527" , s1); hm.put("9522" , s2); hm.put("9524" , s3); hm.put("9529" , s4); hm.put("9520" , s5); Set<String> set = hm.keySet(); for (String key : set) { Student value = hm.get(key); System.out.println(key + "---" + value.getName() + "---" + value.getAge()); } } } class Student { private String name; private int age; public Student () { } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 public class HashMapDemo4 { public static void main (String[] args) { HashMap<Student, String> hm = new HashMap <Student, String>(); Student s1 = new Student ("貂蝉" , 27 ); Student s2 = new Student ("王昭君" , 30 ); Student s3 = new Student ("西施" , 33 ); Student s4 = new Student ("杨玉环" , 35 ); Student s5 = new Student ("貂蝉" , 27 ); hm.put(s1, "8888" ); hm.put(s2, "6666" ); hm.put(s3, "5555" ); hm.put(s4, "7777" ); hm.put(s5, "9999" ); Set<Student> set = hm.keySet(); for (Student key : set) { String value = hm.get(key); System.out.println(key.getName() + "---" + key.getAge() + "---" + value); } } } class Student { private String name; private int age; public Student () { } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
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 public class LinkedHashMapDemo { public static void main (String[] args) { LinkedHashMap<String, String> hm = new LinkedHashMap <String, String>(); hm.put("2345" , "hello" ); hm.put("1234" , "world" ); hm.put("3456" , "java" ); hm.put("1234" , "javaee" ); hm.put("3456" , "android" ); Set<String> set = hm.keySet(); for (String key : set) { String value = hm.get(key); System.out.println(key + "---" + value); } } }
Hashtable集合练习 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class HashtableDemo { public static void main (String[] args) { Hashtable<String, String> hm = new Hashtable <String, String>(); hm.put("it001" , "hello" ); System.out.println(hm); } }
TreeMap集合练习 A:TreeMap<String,String>
B:TreeMap<Student,String>
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 public class TreeMapDemo { public static void main (String[] args) { TreeMap<String, String> tm = new TreeMap <String, String>(); tm.put("hello" , "你好" ); tm.put("world" , "世界" ); tm.put("java" , "爪哇" ); tm.put("world" , "世界2" ); tm.put("javaee" , "爪哇EE" ); Set<String> set = tm.keySet(); for (String key : set) { String value = tm.get(key); System.out.println(key + "---" + value); } } }
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 public class TreeMapDemo2 { public static void main (String[] args) { TreeMap<Student, String> tm = new TreeMap <Student, String>(new Comparator <Student>() { @Override public int compare (Student s1, Student s2) { int num = s1.getAge() - s2.getAge(); int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; return num2; } }); Student s1 = new Student ("潘安" , 30 ); Student s2 = new Student ("柳下惠" , 35 ); Student s3 = new Student ("唐伯虎" , 33 ); Student s4 = new Student ("唐伯虎" , 33 ); Student s5 = new Student ("唐伯虎" , 34 ); tm.put(s1, "宋朝" ); tm.put(s2, "元朝" ); tm.put(s3, "明朝" ); tm.put(s4, "汉朝" ); tm.put(s5, "汉朝" ); Set<Student> set = tm.keySet(); for (Student key : set) { String value = tm.get(key); System.out.println(key.getName() + "---" + key.getAge() + "---" + value); } } } class Student { private String name; private int age; public Student () { } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
案例 A:统计一个字符串中每个字符出现的次数
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 public class TreeMapDemo { public static void main (String[] args) { Scanner sc = new Scanner (System.in); System.out.println("请输入一个字符串:" ); String line = sc.nextLine(); TreeMap<Character, Integer> tm = new TreeMap <Character, Integer>(); char [] chs = line.toCharArray(); for (char ch : chs) { Integer i = tm.get(ch); if (i == null ) { tm.put(ch, 1 ); } else { i++; tm.put(ch, i); } } StringBuilder sb = new StringBuilder (); Set<Character> set = tm.keySet(); for (Character key : set) { Integer value = tm.get(key); sb.append(key).append("(" ).append(value).append(")" ); } String result = sb.toString(); System.out.println("result:" + result); } }
B:集合的嵌套遍历
a:HashMap嵌套HashMap
b:HashMap嵌套ArrayList
c:ArrayList嵌套HashMap
d:多层嵌套
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 46 47 public class HashMapDemo { public static void main (String[] args) { HashMap<String, HashMap<String, Integer>> javaMap = new HashMap <String, HashMap<String, Integer>>(); HashMap<String, Integer> jcMap = new HashMap <String, Integer>(); jcMap.put("陈玉楼" , 20 ); jcMap.put("高跃" , 22 ); javaMap.put("基础班" , jcMap); HashMap<String, Integer> jyMap = new HashMap <String, Integer>(); jyMap.put("李杰" , 21 ); jyMap.put("曹石磊" , 23 ); javaMap.put("就业班" , jyMap); Set<String> javaMapSet = javaMap.keySet(); for (String javaMapKey : javaMapSet) { System.out.println(javaMapKey); HashMap<String, Integer> javaMapValue = javaMap.get(javaMapKey); Set<String> javaMapValueSet = javaMapValue.keySet(); for (String javaMapValueKey : javaMapValueSet) { Integer javaMapValueValue = javaMapValue.get(javaMapValueKey); System.out.println("\t" + javaMapValueKey + "---" + javaMapValueValue); } } } }
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 46 47 48 49 public class HashMapIncludeArrayListDemo { public static void main (String[] args) { HashMap<String, ArrayList<String>> hm = new HashMap <String, ArrayList<String>>(); ArrayList<String> array1 = new ArrayList <String>(); array1.add("吕布" ); array1.add("周瑜" ); hm.put("三国演义" , array1); ArrayList<String> array2 = new ArrayList <String>(); array2.add("令狐冲" ); array2.add("林平之" ); hm.put("笑傲江湖" , array2); ArrayList<String> array3 = new ArrayList <String>(); array3.add("郭靖" ); array3.add("杨过" ); hm.put("神雕侠侣" , array3); Set<String> set = hm.keySet(); for (String key : set) { System.out.println(key); ArrayList<String> value = hm.get(key); for (String s : value) { System.out.println("\t" + s); } } } }
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 46 47 48 49 50 51 public class ArrayListIncludeHashMapDemo { public static void main (String[] args) { ArrayList<HashMap<String, String>> array = new ArrayList <HashMap<String, String>>(); HashMap<String, String> hm1 = new HashMap <String, String>(); hm1.put("周瑜" , "小乔" ); hm1.put("吕布" , "貂蝉" ); array.add(hm1); HashMap<String, String> hm2 = new HashMap <String, String>(); hm2.put("郭靖" , "黄蓉" ); hm2.put("杨过" , "小龙女" ); array.add(hm2); HashMap<String, String> hm3 = new HashMap <String, String>(); hm3.put("令狐冲" , "任盈盈" ); hm3.put("林平之" , "岳灵珊" ); array.add(hm3); for (HashMap<String, String> hm : array) { Set<String> set = hm.keySet(); for (String key : set) { String value = hm.get(key); System.out.println(key + "---" + value); } } } }
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 public class HashMapDemo { public static void main (String[] args) { HashMap<String, HashMap<String, ArrayList<Student>>> javaMap = new HashMap <String, HashMap<String, ArrayList<Student>>>(); HashMap<String, ArrayList<Student>> bjjavaMap = new HashMap <String, ArrayList<Student>>(); ArrayList<Student> array1 = new ArrayList <Student>(); Student s1 = new Student ("林青霞" , 27 ); Student s2 = new Student ("巩俐" , 30 ); array1.add(s1); array1.add(s2); ArrayList<Student> array2 = new ArrayList <Student>(); Student s3 = new Student ("赵雅芝" , 28 ); Student s4 = new Student ("武鑫" , 29 ); array2.add(s3); array2.add(s4); bjjavaMap.put("基础班" , array1); bjjavaMap.put("就业班" , array2); javaMap.put("北京校区" , bjjavaMap); HashMap<String, ArrayList<Student>> xajavaMap = new HashMap <String, ArrayList<Student>>(); ArrayList<Student> array3 = new ArrayList <Student>(); Student s5 = new Student ("范冰冰" , 27 ); Student s6 = new Student ("刘意" , 30 ); array3.add(s5); array3.add(s6); ArrayList<Student> array4 = new ArrayList <Student>(); Student s7 = new Student ("李冰冰" , 28 ); Student s8 = new Student ("张志豪" , 29 ); array4.add(s7); array4.add(s8); xajavaMap.put("基础班" , array3); xajavaMap.put("就业班" , array4); javaMap.put("西安校区" , xajavaMap); Set<String> javaMapSet = javaMap.keySet(); for (String javaMapKey : javaMapSet) { System.out.println(javaMapKey); HashMap<String, ArrayList<Student>> javaMapValue = javaMap.get(javaMapKey); Set<String> javaMapValueSet = javaMapValue.keySet(); for (String javaMapValueKey : javaMapValueSet) { System.out.println("\t" + javaMapValueKey); ArrayList<Student> javaMapValueValue = javaMapValue.get(javaMapValueKey); for (Student s : javaMapValueValue) { System.out.println("\t\t" + s.getName() + "---" + s.getAge()); } } } } } class Student { private String name; private int age; public Student () { } public Student (String name, int age) { super (); this .name = name; this .age = age; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
Collections集合工具类 介绍 Collections 是针对集合进行操作的工具类,都是静态方法。
Collection和Collections A:Collection 是单列集合的顶层接口,有两个子接口List和Set
B:Collections 是针对集合进行操作的工具类,可以对集合进行排序和查找等
常用方法 1 2 3 4 5 6 A: public static <T extends Comparable <? super T>> void sort (List<T> list) :根据元素的自然顺序 对指定列表按升序进行排序。 public static <T> void sort (List<T> list, Comparator<? super T> c) :根据指定比较器产生的顺序对指定列表进行排序。 B: public static <T> int binarySearch (List<? extends Comparable<? super T>> list, T key) :使用二分搜索法搜索指定列表,以获得指定对象。 C: public static <T extends Object & Comparable<? super T>> T max (Collection<? extends T> coll) :根据元素的自然顺序,返回给定 collection 的最大元素。 D: public static void reverse (List<?> list) :反转指定列表中元素的顺序。 E: public static void shuffle (List<?> list) :使用默认随机源对指定列表进行置换。所有置换发生的可能性都是大致相等的。
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 public class CollectionsDemo { public static void main (String[] args) { ArrayList<Integer> list = new ArrayList <Integer>(); list.add(30 ); list.add(20 ); list.add(50 ); list.add(10 ); list.add(40 ); System.out.println("list:" + list); System.out.println("binarySearch:" + Collections.binarySearch(list, 30 )); System.out.println("binarySearch:" + Collections.binarySearch(list, 300 )); System.out.println("binarySearch:" + Collections.binarySearch(list, 3 )); System.out.println("max:" + Collections.max(list)); } }
案例 A:ArrayList集合存储自定义对象的排序
B:模拟斗地主洗牌和发牌
C:模拟斗地主洗牌和发牌并对牌进行排序
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 public class CollectionsDemo { public static void main (String[] args) { List<Student> list = new ArrayList <Student>(); Student s1 = new Student ("林青霞" , 27 ); Student s2 = new Student ("风清扬" , 30 ); Student s3 = new Student ("刘晓曲" , 28 ); Student s4 = new Student ("武鑫" , 29 ); Student s5 = new Student ("林青霞" , 27 ); list.add(s1); list.add(s2); list.add(s3); list.add(s4); list.add(s5); Collections.sort(list, new Comparator <Student>() { @Override public int compare (Student s1, Student s2) { int num = s2.getAge() - s1.getAge(); int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; return num2; } }); for (Student s : list) { System.out.println(s.getName() + "---" + s.getAge()); } } } class Student implements Comparable <Student> { private String name; private int age; public Student () { } public Student (String name, int age) { super (); this .name = name; this .age = age; } public int compareTo (Student s) { int num = this .age - s.age; int num2 = num == 0 ? this .name.compareTo(s.name) : num; return num2; } public String getName () { return name; } public void setName (String name) { this .name = name; } public int getAge () { return age; } public void setAge (int age) { this .age = age; } }
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 public class PokerDemo { public static void main (String[] args) { ArrayList<String> arrayList = new ArrayList <String>(); String[] colors = { "♠" , "♥" , "♣" , "♦" }; String[] numbers = { "A" , "2" , "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" , "J" , "Q" , "K" }; for (String color : colors) { for (String number : numbers) { arrayList.add(color.concat(number)); } } arrayList.add("小王" ); arrayList.add("大王" ); Collections.shuffle(arrayList); ArrayList<String> liuDeHua = new ArrayList <String>(); ArrayList<String> linQingXia = new ArrayList <String>(); ArrayList<String> liuYi = new ArrayList <String>(); ArrayList<String> diPai = new ArrayList <String>(); for (int x = 0 ; x < arrayList.size(); x++) { if (x >= arrayList.size() - 3 ) { diPai.add(arrayList.get(x)); } else if (x % 3 == 0 ) { liuDeHua.add(arrayList.get(x)); } else if (x % 3 == 1 ) { linQingXia.add(arrayList.get(x)); } else if (x % 3 == 2 ) { liuYi.add(arrayList.get(x)); } } lookPoker("刘德华" , liuDeHua); lookPoker("林青霞" , linQingXia); lookPoker("刘意" , liuYi); lookPoker("底牌" , diPai); } public static void lookPoker (String name, ArrayList<String> array) { System.out.print(name + "的牌是:" ); for (String s : array) { System.out.print(s + " " ); } System.out.println(); } }
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 public class PokerDemo { public static void main (String[] args) { HashMap<Integer, String> hm = new HashMap <Integer, String>(); ArrayList<Integer> array = new ArrayList <Integer>(); String[] colors = { "♠" , "♥" , "♣" , "♦" }; String[] numbers = { "3" , "4" , "5" , "6" , "7" , "8" , "9" , "10" , "J" , "Q" , "K" , "A" , "2" , }; int index = 0 ; for (String number : numbers) { for (String color : colors) { String poker = color.concat(number); hm.put(index, poker); array.add(index); index++; } } hm.put(index, "小王" ); array.add(index); index++; hm.put(index, "大王" ); array.add(index); Collections.shuffle(array); TreeSet<Integer> fengQingYang = new TreeSet <Integer>(); TreeSet<Integer> linQingXia = new TreeSet <Integer>(); TreeSet<Integer> liuYi = new TreeSet <Integer>(); TreeSet<Integer> diPai = new TreeSet <Integer>(); for (int x = 0 ; x < array.size(); x++) { if (x >= array.size() - 3 ) { diPai.add(array.get(x)); } else if (x % 3 == 0 ) { fengQingYang.add(array.get(x)); } else if (x % 3 == 1 ) { linQingXia.add(array.get(x)); } else if (x % 3 == 2 ) { liuYi.add(array.get(x)); } } lookPoker("风清扬" , fengQingYang, hm); lookPoker("林青霞" , linQingXia, hm); lookPoker("刘意" , liuYi, hm); lookPoker("底牌" , diPai, hm); } public static void lookPoker (String name, TreeSet<Integer> ts, HashMap<Integer, String> hm) { System.out.print(name + "的牌是:" ); for (Integer key : ts) { String value = hm.get(key); System.out.print(value + " " ); } System.out.println(); } }
常见数据结构 栈 先进后出
队列 先进先出
数组 查询快,增删慢
链表 查询慢,增删快
树
哈希表 是一个元素为链表的数组。综合了数组和链表的好处。