Java进阶之路05-(泛型.集合2)

文中关键字:泛型     LinkedList集合 Vector集合 Map集合 Set集合

需求:ArrayList集合存储元素并遍历
问题:使用ArrayList集合存储元素遍历的时候,按照正常的操作出现了问题,
当前ArrayList集合中存储了两种类型的元素分别String和Integer类型,在遍历的时候,使用的是String接收的,对于Integer类型就出现了异常!
使用集合并添加元素时:
array.add("hello") ;
array.add("world") ;
array.add("java") ;
array.add(new Integer(100)) ;
在遍历的过程中会出现:
//java.lang.ClassCastException:类转换异常
回想数组:
String[] str = new String[3] ;
str[0] = "hello" ;
str[1] = "world" ;
str[2] = 100 ; 错误的
数组直接定义了存储的类型,防止出现其他类型的元素,集合能不能也像数组一样,直接规定我们集合的存储类型,针对这种情况
出现了一种技术:泛型
<数据类型> --- 引用数据类型


泛型:将明确的集合类型的工作推迟到了创建对象或者调用方法的时候,属于一种参数化类型,可以作为参数传递.
泛型的好处:
1)将运行时期异常提前到了编译时期
2)优化了设计,解决了黄色警告线问题
3)避免了强制类型转换


泛型的引出可以提供程序的安全性!
-----------------------------------------------------------
/**
 * 使用ArrayList集合存储自定义对象并遍历,加入泛型
 *
 */
 导包:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {

//创建集合对象
ArrayList<Student> array = new ArrayList<Student>() ;  //=号右边的泛型:泛型推断

//创建学生对象
Student s1 = new Student("王昭君",25) ; 
Student s2 = new Student("西施",27) ; 
Student s3 = new Student("杨贵妃",25) ; 
Student s4 = new Student("貂蝉",28) ; 

//添加到集合中
array.add(s1) ;
array.add(s2) ;
array.add(s3) ;
array.add(s4) ;

//遍历1.获取迭代器
Iterator<Student> it = array.iterator() ;
while(it.hasNext()) {
Student s = it.next() ;
System.out.println(s.getName()+"----"+s.getAge());
}
System.out.println("------------------");

//遍历2.普通for循环
for(int x = 0 ; x < array.size() ; x ++) {
Student s = array.get(x) ;
System.out.println(s.getName()+"---"+s.getAge());
}
}
上面所创建的是下面Student类的对象:
Student类代码如下:
public 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;
}
}
-----------------------------------------------------------
在早期的时候,使用Object类型代表任意类型,向上转型没有问题,
使用向下转型的时候,可能会出现问题(需要的类型有问题),这个时候就需要引入泛型操作
看API,接口,类,方法上有<E> ,都是泛型的意思
创建一个Objecttool工具类:
(将代码复制到你所创建的Objecttool类中)
 private T obj ;

public T getObj() {
return obj ;
}

public void setObj(T obj) {
this.obj = obj ;
}
测试类主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {

//创建ObjectTool对象
ObjectTool<String> ot = new ObjectTool<String>() ;

//赋值
ot.setObj(new String("高圆圆"));
String s = ot.getObj() ;
System.out.println("姓名是:"+s);

//ot.setObj(new Integer(27)); 直接隐藏的问题解决了
System.out.println("---------------");

ObjectTool<Integer> ot2 = new ObjectTool<Integer>() ;
ot2.setObj(new Integer(27));
//ot2.setObj(new String("高圆圆"));
Integer i = ot2.getObj() ;
System.out.println("年龄是:"+i);
}
-----------------------------------------------------------
可以将泛型定义在类上,可不可以在类上不定义泛型,将泛型应用在方法上?
泛型是可以在方法上定义的例如:
public <T> void show(T t) {
System.out.println(t);
}  
-----------------------------------------------------------
泛型的应用:在接口中,类中,方法上应用,在集合中应用最多!


//接口中泛型,子实现类的第一种情况,就是已经知道是什么类型了此处是String类型,Inter是一个接口
/**
*public class InterImpl implements Inter<String> {
* public void show() {
* System.out.println("hello");
* }
*}
*/


//第二种情况,就是不知道具体的类型是什么,此处没有指明是什么类型
public class InterImpl<T> implements Inter<T>{
@Override
public void show() {
System.out.println("hello");
}
}
-----------------------------------------------------------
泛型高级(通配符)
<?>  :代表任意类型Object类型,或者任意的Java类 
<? extends E>:向下限定,E的子类或者E这个类型
<? super E>:向上限定,E及其他的父类
-----------------------------------------------------------
/** 
 *ArrayList是List接口中常用的一个子实现类
 *
 * 遍历功能:
 * 1)一个是Collection的iterator()
 * 2)size()和get(int index)普通for循环
 *存储字符串并遍历元素
 */
 导包:
import java.util.ArrayList;
import java.util.Iterator;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {

//创建集合对象
ArrayList list = new ArrayList() ;

//添加元素
list.add("hello") ;
list.add("world") ;
list.add("java") ;


//遍历
//获取迭代器
Iterator it = list.iterator() ;
while(it.hasNext()) {
String s = (String)it.next() ;
System.out.println(s);
}

System.out.println("-----------------------");

for(int x = 0 ; x < list.size() ; x ++) {
String s = (String) list.get(x) ;
System.out.println(s);
}

}
-----------------------------------------------------------
Vector集合
  底层是一种可增长对象数组,查询快,增删慢
  线程安全,同步,执行效率高
 
特有功能:
public void addElement(Object obj)------->add(Object obj)
public Enumeration elements():返回此向量的枚举--->相当于:public Iterator iterator()
  boolean hasMoreElements()  --->boolean hasNext() ;
  Object nextElement()   --->Object next() ;
-----------------------------------------------------------
LinkedList集合的特点:先进后出
底层是一种链表实现,查询慢,增删快
线程不安全的,不同步,执行效率高
特有功能:
添加功能
addFirst(Object e):将指定的元素插入到列表的开头
addLast(object e):将指定的元素添加到列表末尾
获取功能:
getFirst():获取列表第一个元素
getLast():获取列表第二个元素


删除功能
public Object removeFirst()移除并返回此列表的第一个元素。
public Object removeLast()
-----------------------------------------------------------
/**
 *需求:给集合中添加重复的元素(字符串类型),将重复的元素从集合去除掉!
 *
 *思路:
 * 1)创建一个旧集合,添加重复元素
 * 2)创建一个新集合
 * 3)遍历旧集合中的元素获取到每一个元素
 * 在旧集合中判断新集合中是否包含旧集合中的元素
 * 包含,不搭理
 * 不包含,添加到新集合中
 * 4)遍历新集合
 */
 导包:
import java.util.ArrayList;
import java.util.Iterator;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {

//创建一个集合
ArrayList list = new ArrayList() ;

//添加元素
list.add("hello") ;
list.add("world") ;
list.add("java") ;
list.add("javaee") ;
list.add("hello") ;
list.add("world") ;
list.add("hello") ;
list.add("javaee") ;
list.add("android") ;
list.add("python") ;
list.add("php") ;
list.add("php") ;

//创建一个新的集合
ArrayList newList = new ArrayList() ;

//遍历旧集合
Iterator it = list.iterator() ;
while(it.hasNext()) {
String s = (String) it.next() ;

//判断新集合中是否包含旧集合中的元素
if(!newList.contains(s)) {
newList.add(s) ;
}
}

//遍历新集合
Iterator it2 = newList.iterator() ;
while(it2.hasNext()) {
String s = (String) it2.next() ;
System.out.println(s);
}
}
-----------------------------------------------------------
/**
 * 去重集合中重复的元素
 * 假设:现在的需求:不允许新建一个集合去完成,怎么办? 
 */
 导包:
import java.util.ArrayList;
import java.util.Iterator;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {
//创建ArrayList集合对象
ArrayList  array = new ArrayList() ;
//添加元素
array.add("hello") ;
array.add("world") ;
array.add("java") ;
array.add("javaee") ;
array.add("hello") ;
array.add("world") ;
array.add("hello") ;
array.add("javaee") ;
/**
* 引入选择排序,
* 用0索引对应的元素依次和后面索引对应的元素进行比较
* 如果前面的元素和后面的元素重复了,把后面元的干掉
* 依次1索引....
*/
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 it = array.iterator() ;
while(it.hasNext()) {
String s = (String) it.next() ;
System.out.println(s);
}
}
-----------------------------------------------------------
/**
 * 需求:使用集合ArrayList存储自定义对象(Student),去除重复的对象(成员变量的值一样,看成一个人)
 * 
 * 问题:按照存储字符串(新建集合的思想)的形式来去存储自定义对象,发现自定义对象并没有去重,为什么?
 * contains方法底层依赖于equals方法
 * equals方法默认比较的是地址值,如果想让equals()方法比较他们的内容是否相同,需要重写equals(),也就意味着存储自定义类,必须重写
 * equals()方法,这样才能比较的是这些对象的内容是否相同
 */
 导包:
import java.util.ArrayList;
import java.util.Iterator;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {
//创建一个ArrayList集合
ArrayList array = new ArrayList() ;
//创建4个学生对象
Student s1 = new Student("高圆圆", 27);
Student s2 = new Student("文章", 29);
Student s3 = new Student("王力宏", 30);
Student s4 = new Student("高圆圆", 27);
Student s5 = new Student("高圆圆", 29);

array.add(s1) ;
array.add(s2) ;
array.add(s3) ;
array.add(s4) ;
array.add(s5) ;

//创建一个新集合
ArrayList newArray = new ArrayList() ;

//遍历旧集合
Iterator it = array.iterator() ;
while(it.hasNext()) {
Student s = (Student)it.next() ;
//判断,新集合中是否包含
if(!newArray.contains(s)) {
newArray.add(s) ;
}
}
//遍历新集合
Iterator it2 = newArray.iterator() ;
while(it2.hasNext()) {
Student s= (Student)it2.next();
System.out.println(s.getName()+"---"+s.getAge());
}
}
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;
}
@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;
}
-----------------------------------------------------------
JDK5以后的新特性
/**
 * 可变参数:当一个方法的参数个数不确定的时候,要使用可变参数
 *
 * 格式:
 * 修饰符 返回值类型  方法名(数据类型...变量名){...}
 * 
 * 注意:
 * 1)变量名:看成一个数组
 * 2)使用的时候数据类型...
 *
 * 注意:根据具体的需求去完成,一般情况,知道有这个特性就可以了
 *
 *求数据之和
 */


主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {
int a = 10 ;
int b = 20 ;
int result = sum(a,b) ;
System.out.println("result:"+result);

int c = 30 ;
int result2 = sum(a,b,c);
System.out.println("result2:"+result2);

int d = 40 ;
int result3 = sum(a,b,c,d);
System.out.println("result3:"+result3);

//当我们的参数不确定的情况下,就可以使用jdk5一个特性:可变参数
System.out.println(sum(a,b,c,d,50));
}
//定义一个参数不确定的方法,通过可变参数操作
public static int sum(int...a) {
//求和:将a是多个参数的,看成数组

//先定义最终结果变量
int result = 0 ;
//增强for遍历可变参数a
for(int n :a) {
result += n ;
}
return result;

-----------------------------------------------------------
JDK5以后的新特性 
ArrayList集合存储自定义对象并遍历,有几种方式?
  Iterator iterator() ;
  listIterator listiterator();(可以不写)
  普通for循环:size()/get(int index)
  增强for循环
-----------------------------------------------------------
JDK5以后的新特性:
针对数组操作的工具类:Arrays,提供了一个方法:
public static <T> List<T> asList(T... a) :将数组转换成固定大小的集合
注意:如果使用此方法,那么集合的长度不可变
导包:
import java.util.Arrays;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
//定义数组:
/*String[] str = {"hello","world","java"} ;

//将数组转换成固定大小的集合
List<String> list = Arrays.asList(str) ;*/

List<String> list = Arrays.asList("hello","world","java") ;

//添加元素
//list.add("javaee") ;// java.lang.UnsupportedOperationException :集合固定的,长度是固定的

// list.remove("world") ;
list.set(1, "javaee"); //修改集合中的元素内容
//增强for
for(String s:list) {
System.out.println(s);
}
}
-----------------------------------------------------------
JDK5以后的新特性
 * 增强for,静态导入,可变参数,泛型,自动拆装箱...
 * 增强for循环的格式
 * for(数据大类型  变量名 : 数组或者集合对象名){
 * 输出变量即可!
 * }
 * 
 * 增强for的出现时替代迭代器的,所以在遍历集合或者遍历数组就可以使用增强for去完成
 * 
 * 增强for循环的弊端:如果集合的对象是null,如果再次对集合操作,就会出现异常
 * 对集合进行判断,非空判断解决
 * 
 * 练习:ArrayList集合存储自定义对象并遍历,有几种方式?
 * Iterator iterator() ;
 * listIterator listiterator();(可以不写)
 * 普通for循环:size()/get(int index)
 * 增强for循环
 */
 导包:
import java.util.ArrayList;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {

//定义一个数组,静态初始化
int[] arr = {11,22,33,44,55} ;
//正常的方式,普通for循环
for(int x = 0 ; x < arr.length ; x ++) {
System.out.println(arr[x]);
}

System.out.println("---------------------");

//增强for循环
for(int a :arr) {
System.out.println(a);
}

//定义一个字符串类型的数组
String[] str = {"hello","world","java","javaee"} ;
//直接增强for
for(String s : str) {
System.out.println(s);
}
System.out.println("-------------------------");

//创建一个集合
List<String> list = new ArrayList<String>() ;
list.add("hello") ;
list.add("world") ;
list.add("java") ;
//直接增强for
for(String s:list) {
System.out.println(s);
}

list = null ;
//NullPointerException
if(list !=null) {
for(String s:list) {
System.out.println(s);
}
}
System.out.println("------------------------");

//遍历list集合,判断如果有"world"元素,给集合添加一个元素(javaee)
/*for(String s: list) {  //使用size()和get(int index)相结合...
//java.util.ConcurrentModificationException :并发修改异常 
//增强for的出现就是用来替代迭代器的!
if("world".equals(s)) {
list.add("javaee");
}
}
System.out.println("list:"+list);*/
}
-----------------------------------------------------------
JDK5以后的新特性
静态导入
//1).导入到方法的级别
import static java.lang.Math.abs;
//2).可以使用带前缀的方式
System.out.println(java.lang.Math.abs(-100));
//3).在测试,直接写方法名,前提静态导入
通常所使用的导包;
System.out.println(abs(-100));
//4).本身当前的某个类中的方法名和需要被静态导入的方法名一样,必须加上前缀
-----------------------------------------------------------
重点:
 /**
 *需求
 *集合的嵌套遍历
 *有一个Java基础班,里面有很多学生,把一个班级集合:ArrayList<Student>
 *不止一个Java基础班,这个时候就定义大集合:ArrayList<ArrayList<Student>>
 *有三个基础班,分别遍历每一个班里面学生信息:(name,age) 
 */
导包:
import java.util.ArrayList;
import java.util.HashSet;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {
//创建一个大的集合
ArrayList<ArrayList<Student>> bigArrayList = new ArrayList<ArrayList<Student>>() ;
//创建第一个班的集合对象
ArrayList<Student> firstArray = new ArrayList<Student>() ;
//创建学生对象
Student s1 = new Student("曹操",35) ;//后知后觉
Student s2 = new Student("诸葛亮", 29);//先知先觉
Student s3 = new Student("蒋干", 30) ;//不知不觉

//给第一个班添加元素
firstArray.add(s1) ;
firstArray.add(s2) ;
firstArray.add(s3) ;

//将第一个集合添加到大集合中
bigArrayList.add(firstArray) ;

//创建第二个班集合对象
ArrayList<Student> secondArray = new ArrayList<Student>() ;
Student s11 = new Student("宋江",38) ;
Student s22 = new Student("鲁智深", 29);
Student s33 = new Student("武松", 30) ;

secondArray.add(s11) ;
secondArray.add(s22) ;
secondArray.add(s33) ;

//添加到大集合
bigArrayList.add(secondArray) ;

//创建第三个集合对象
ArrayList<Student> thirdArray = new ArrayList<Student>() ;
Student s111 = new Student("高圆圆",38) ;
Student s222 = new Student("唐嫣", 29);
Student s333 = new Student("刘若英", 30) ;

thirdArray.add(s111) ;
thirdArray.add(s222) ;
thirdArray.add(s333) ;
//添加到集合
bigArrayList.add(thirdArray) ;

//增强for遍历:大集合
for(ArrayList<Student> array: bigArrayList) {
for(Student s:array) {
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
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;
}
-----------------------------------------------------------
/**
 * 
 * 需求:求10个1~20之间的随机数,要求数据不能重复 set集合
 *分析:
 * 可以使用数组,数组的长度固定,不够好,使用集合去做
 *创建一个随机数类对象
 * Random
 * 获取指定的随机数的范围:
 * int nextInt() ;  获取的int类型的范围
 * int nextInt(int n) ;获取1~n之间的数据 ,[0,n)
 *
 * 创建一个ArrayList集合对象,元素类型:Integer类型
 * 定义统计遍历:count 是从0开始
 * 判断如果统计遍历小于10
 * 先计算出1-20之间的随机数,还需要判断集合中是否包含这些元素
 * 如果不包含,添加,count++
 * 包含,重复,不搭理了....
 * 大于10,不搭理
 * 遍历即可
 */
 导包:
import java.util.ArrayList;
import java.util.Random;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {
//创建随机数类对象
Random r = new Random() ;

//创建一个ArrayList集合
ArrayList<Integer> array = new ArrayList<Integer>() ;

//定义统计变量
int count = 0 ;

//判断统计变量的个数
while(count <10) {
//个数符合的情况下,计算出1-20之间的随机数
int number = r.nextInt(20) +1 ;
//需要判断集合总是发包含这个number
if(!array.contains(number)) {
array.add(number) ;
count ++ ;
}
}
//增强for
for(Integer i : array) {
System.out.println(i);
}
}
********************************************************************
/**
 * 需求:有很多学生,学生有姓名,有学号,根据学生的学号查找学生?
 * 之前学习的集合,可以将姓名,学号作为学生类的中两个成员变量,创建集合的时候存储这个类型,可以的
 * 
 * 关键只知道学生学号,通过学号找姓名
 * Key Value
 *
 * 学号1 姓名1
 * 学号2 姓名2
 * 学号3 姓名3
 * 学号1(重复的键) 姓名4
 * 
 * Java针对这种技术----->Map集合 ,键值的映射关系的一种集合(接口)
 * 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。 
 * Map<K,V> ,在Map集合中,只针对键有效,跟值无关 Map接口的子实现类:HashMap和TreeMap
 * 
 * 面试题:
 * Map集合和Collection的区别?
 *
 * Map集合:是一种键和值的映射关系(双列集合) 当作为:夫妻对
 * Collection集合:单列集合,只能存储一种类型的元素,当作为:光棍
 * 间接关系:HashSet依赖于Map接口的子实现类HashMap的
 *   TreeSet依赖于Map接口的子实现类TreeMap的
 * 
 * 
 * Map接口的功能:
 * V put(K key,V value) :添加功能:将指定的值和键关联起来
 * 如果当前的这个键是一次存储,则返回值null
 * 如果不是第一次存储,返回值是第一次对应的值,当前的值就把之前的键对应的值替换掉!
 *
 * 获取功能
 * Set<Map.Entry<K,V>> entrySet() :和Map集合的遍历有关系(键值对对象)
 * Set<K> keySet():获取映射关系中所有的键的集合
 * int size()返回此映射中的键-值映射关系数
 * 删除功能
 * void clear():删除所有映射关系
 *   Vremove(Object key)如果存在一个键的映射关系,则将其从此映射中移除
 *  
 *   判断功能:
 * boolean containsKey(Object key)如果此映射包含指定键的映射关系,则返回 true
 * boolean containsValue(Object value):映射关系中是否包含指定的值
 * boolean isEmpty():判断映射关系是否为空
 *
 */
 导包:
import java.util.HashMap;
import java.util.Map;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {
//创建Map集合对象
Map<String, String> map = new HashMap<String,String>() ;
//System.out.println("map:"+map);遍历map集合

//添加功能的作用
System.out.println("put():"+map.put("文章", "马伊琍"));
System.out.println("put():"+map.put("文章", "姚笛"));

//添加元素
/*map.put("高圆圆", "赵又廷") ;
map.put("周杰伦", "昆凌") ;
map.put("黄晓明", "babay") ;
map.put("文章", "马伊琍") ;*/

//void clear():删除所有映射关系
//map.clear(); 

//V remove(Object key)如果存在一个键的映射关系,则将其从此映射中移除,返回的是该对应的值
//System.out.println("remove():"+map.remove("黄晓明"));

//boolean containsKey(Object key)如果此映射包含指定键的映射关系,则返回 true
/*System.out.println("containsKey():"+map.containsKey("杨过"));
System.out.println("containsKey():"+map.containsKey("高圆圆"));*/

//boolean containsValue(Object value):映射关系中是否包含指定的值
//System.out.println("containsValue():"+map.containsValue("昆凌"));

System.out.println("map:"+map); //{key1=value1, key2=value2,.}
}
-----------------------------------------------------------
/**
 * 这种遍历方式实际开发中经常用的...
 * Set<K> keySet():获取映射关系中所有的键的集合
 * 
 * V get(Object key):通过键找值
 * 转换法:
 * 1)将所有的丈夫集中起来
 * 2)让丈夫对应的妻子
 * 3)将他们遍历出来
 * 
 * 思路:
 * 1)获取所有的键的集合
 * 2)通过键找它对应的值
 * 3)遍历即可
 */
 导包:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {

//创建Map集合
Map<String,String> map = new HashMap<String,String>() ;

//添加元素
map.put("杨过", "小龙女") ;
map.put("郭靖", "黄蓉") ;
map.put("陈旋风", "梅超风") ;
map.put("高圆圆", "赵又廷") ;

//遍历
//先获取所有的键的集合
Set<String> set = map.keySet() ;
//遍历素有的键,获取每一个键
for(String key :set) {
//通过键找值
String value = map.get(key) ;
System.out.println(key+"="+value);
}

-----------------------------------------------------------
/**
 * Map集合的另一种方式的遍历 Set<Map.Entry<K,V>> entrySet() :和Map集合的遍历有关系(键值对对象)
 * 
 * 转发法: 1)获取所有的结婚证 2)通过结婚证分别找对应的丈夫和妻子 3)遍历输出
 * 
 * 
 * 思路: 1)获取所有的键值对象entrySet()
 *  2) K getKey() 和 v getValue(),获取键值对对象中的每个键和每个值
 *  3)遍历
 */
 导包:
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {


// 创建Map集合对象
Map<String, String> map = new HashMap<String, String>();


// 添加元素
map.put("杨过", "小龙女");
map.put("郭靖", "黄蓉");
map.put("陈旋风", "梅超风");
map.put("高圆圆", "赵又廷");

//获取所有的键值对对象
Set<Map.Entry<String, String>> entrySet = map.entrySet() ;
//增强for
for(Map.Entry<String, String> entry :entrySet) {
//获取到每一个键值对对象
//通过键值对对象找键和值
String key = entry.getKey() ;
String value = entry.getValue() ;
System.out.println(key+"="+value);
}

-----------------------------------------------------------
先看下下面这段代码:
public static void main(String[] args) {
System.out.println("hello".hashCode());
System.out.println("java".hashCode());
System.out.println("world".hashCode());
System.out.println("world".hashCode());

结果是:
99162322
3254818
113318802
113318802
-----------------------------------------------------------
Set集合和List集合的区别?
 * Set集合:不允许元素重复,唯一的(元素可以为null) ,不能保证迭代的顺序恒久不变(底层哈希表和hascode)
 * 无序(存储和取出不一致)
 * List:允许元素重复,并且存储特点:有序性(存储和取出一致)
 * 通过Set集合存储字符串并遍历
-----------------------------------------------------------
发现Set集合存储元素的时候,可以保证元素的唯一性,原因什么?
 
 * HashSet集合的add方法底层依赖于双列集合HashMap,它依赖于两个方法,HashCode()方法和equals()方法
 * 先比较字符串的HashCode()码值一样,再比较equals()方法
 * 如果hasCode码值一样,还要比较内容是否相同,由于存储String,重写了equals()方法
 * 
 * String本身重写了equals方法,所以不需要再重写了!
 * 
 * 让你用Set集合存储自定义对象遍历 
-----------------------------------------------------------
/**
 * set集合存储自定义对象并遍历
 * 
 * 现在是自定义的类,HashSet集合的add()方法本身依赖于hashCode()和equals()方法
 * 
 * 在Student类中并没重写这两个方法,解决,重写这两个方法
 */
 导包:
import java.util.HashSet;
import java.util.Set; 
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {
Set<Student> set = new HashSet<Student>() ;

//创建学生对象
Student s1 = new Student("高圆圆", 27) ;
Student s2 = new Student("高圆圆", 28) ;
Student s3 = new Student("文章", 30) ;
Student s4 = new Student("马伊琍", 39) ;
Student s5 = new Student("高圆圆", 27) ;

//存储到集合中
set.add(s1) ;
set.add(s2) ;
set.add(s3) ;
set.add(s4) ;
set.add(s5) ;

//遍历
for(Student s : set) {
System.out.println(s.getName()+"---"+s.getAge());
}

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;
}


@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}


@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;
}
-----------------------------------------------------------
如果在开发中,元素唯一性,并且还要保证元素有序(存储和取出一致),使用LinkedHashSet集合
 *
 *
 * 如果开发中要使用集合排序的问题,使用TreeSet集合(红黑树结构),下午分解...
 * 自然排序
 * 选择器排序
 * 
 *LinkedHashSet集合:
 * 底层是一种链接列表和哈希表组成
 * 可以保证元素的唯一性,是由哈希表决定的(hashCode()和equals())
 * 可以保证元素的迭代顺序一致(有序),存储和取出一致,是由链表决定
-----------------------------------------------------------
/**
 * 需求:使用TreeSet集合存储自定义对象(Student类型),并遍历!
 *
 * 你没有告诉,如何排序
 * 按照学生的年龄从小到大进行排序 (主要条件)
 * 
 * 唯一性:
 * 如果成员变量的值一样认为是同一个对象
 */
 导包:
import java.util.TreeSet;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {
//创建TreeSet集合对象
TreeSet<Student> ts  = new TreeSet<Student>() ;//无参构造的方式自然排序

//创建学生对象
Student s1 = new Student("gaoyuanyuan",27) ;
Student s2 = new Student("liushishi",38) ;
Student s3 = new Student("gaoyuanyuan",28) ;
Student s4 = new Student("wanglihong",35) ;
Student s5 = new Student("wanglihong",30) ;
Student s6 = new Student("fengqingy",38) ;
Student s7 = new Student("gaoyuanyuan",27) ;

//java.lang.ClassCastException: org.westos_03.Student cannot be cast to java.lang.Comparable
ts.add(s1) ;
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;

//遍历
for(Student s:ts) {
System.out.println(s.getName()+"---"+s.getAge());
}

}
Student类:
//对于自定义的类型,要实现自然排序,必须自定义的类型必须实现Comparable
//实现接口中的方法,compareTo() :比较方法
public class Student  implements Comparable<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;
}

@Override
public int compareTo(Student s) { //源码 cmp = k.compareTo(t.key)
// return 0;
//按照某种规则,前提必须有这规则
//主要条件:按照年龄从小到大
int num  = this.age - s.age ; //如果年龄相等,不一定是同一个人
//需要自己分析次要条件;
//年龄相同,姓名的内容不一定相同,比较姓名
int num2 = num==0 ? this.name.compareTo(s.getName()) : num ;
return num2 ;
}
}
-----------------------------------------------------------
/*TreeSet集合存储自定义对象(Student)

* 按照姓名的长度从小到大进行比较 :主要条件*/
导包:
import java.util.TreeSet;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {

//创建TreeSet集合,实现对该类型自然排序
TreeSet<Student> ts = new TreeSet<Student> ();

//创建学生对象
Student s1 = new Student("gaoyuanyuan", 27) ;
Student s2 = new Student("zhangguorong",29) ;
Student s3 = new Student("wuqilong", 40) ;
Student s4 = new Student("liushishi", 28) ; 
Student s5 = new Student("fengqingy", 29) ;
Student s6 = new Student("gaoyuanyuan", 22) ;
Student s7 = new Student("gaoyuanyuan", 27) ;


//添加元素
ts.add(s1) ;
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;


//遍历
for(Student s:ts) {
System.out.println(s.getName()+"---"+s.getAge());
}

}
Student类:
public class Student implements Comparable<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;
}

//TreeSet集合保证元素的唯一性,看返回值是否为0
@Override
public int compareTo(Student s) {
//按照姓名的长度进行比较(默认从小到大)
int num = this.getName().length() - s.getName().length() ;

//( 自己分析)次要条件

//如果姓名的长度一样,还要比较他们的内容是否相同
int num2 = num == 0 ? this.getName().compareTo(s.getName()) :num ;

//如果姓名长度和姓名的内容都一致,也不能保证就是同一个人,还要比较年龄
int num3 = num2== 0 ? this.age-s.age :num2 ;
return num3 ;
}
}
-----------------------------------------------------------
/**
 *TreeSet集合的构造方式不同,使用的排序也不同
 * 自然排序:自定义的类实现Compareable接口,然后创建TreeSet对象,通过无参构造形式创建对象
 * 比较器排序 :public TreeSet(Comparator<E> comparator)
 *
 * 两种方式:
 * 1)自定义一个类,该类实现Comparator接口,重写Comparator接口中的compare()方法
 * 2)直接使用接口匿名内部类的方式实现
 *
 *TreeSet集合保证元素唯一,是看返回值是否为0 
 * 保证元素进行排序,两种排序方式
 *
 *使用比较器排序的方式去,遍历Student对象,并且按照姓名长度进行比较
 *
 */
导包:
import java.util.Comparator;
import java.util.TreeSet;
主函数代码如下:(将代码复制到你所创建的类中就可运行)
public static void main(String[] args) {

//创建TreeSet集合对象
//TreeSet<Student> ts = new TreeSet<Student>() ;  //无参构造形式,自然排序
//选择器排序
//Comparator是一个接口
//TreeSet<Student> ts = new TreeSet<Student>(new MyComparator()) ;

//直接使用匿名内部类的方式实现
TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() {


@Override
public int compare(Student s1, Student s2) {

/**
* 自然排序:Comparable 里面compareTo(Student s)

*this---->s1
*s---s
*/
//return 0;
//按照姓名长度进行比较
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("gaoyuanyuan", 27) ;
Student s2 = new Student("zhangguorong",29) ;
Student s3 = new Student("wuqilong", 40) ;
Student s4 = new Student("liushishi", 28) ; 
Student s5 = new Student("fengqingy", 29) ;
Student s6 = new Student("gaoyuanyuan", 22) ;
Student s7 = new Student("gaoyuanyuan", 27) ;


ts.add(s1) ;
ts.add(s2) ;
ts.add(s3) ;
ts.add(s4) ;
ts.add(s5) ;
ts.add(s6) ;
ts.add(s7) ;


//遍历
for(Student s:ts) {
System.out.println(s.getName()+"----"+s.getAge());
}
}
Student类:
public 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;
}
}


Comparator方法类:
//自定义类,该类实现Comparator保证集合中的元素进行比较器排序
导包:
import java.util.Comparator;
代码如下:
public class MyComparator implements Comparator<Student> {


@Override
public int compare(Student s1, Student s2) {

/**
* 自然排序:Comparable 里面compareTo(Student s)

*this---->s1
*s---s
*/
//return 0;
//按照姓名长度进行比较
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 ;
}
}
-----------------------------------------------------------

猜你喜欢

转载自blog.csdn.net/mulinghanxue/article/details/80280597