java类集

在java中必须掌握的知识点,会开发的:
1.面向对象
2.java的类集
3.java IO
4.JDBC

本章目标:
*掌握java设置类集框架的目的
*掌握类集中的各个主要的接口
*掌握Collection接口的作用

类集的作用
类集实际上就是一个动态的对象数组,与一般的对象数组不同,类集上的对象内容可以任意扩充
类集的特征:
*这种框架是高性能的
*框架必须允许不是同类型的类集一相同的方式和高度互相操作方式工作
*类集必须是容易扩展和修改的

对象数组中包含一组对象,但是对象数组的使用的时候存在一个长度的限制,那么类集是专门解决这种限制的,使用类集可以方便的向数组中增加任意多个数据
对象数组的操作中基本上都要保证对象类型的一致性,对于类集而言其本身内部的元素也应该保持一致,不管是何种类型的数据,所有的操作方式都应该是一样的

类集框架的主要接口
在这里插入图片描述
以上的接口必须全部掌握,并且掌握各个接口的主要特点。

接口的继承关系
在这里插入图片描述

Collection接口的使用注意
在一般的开发中,往往很少直接使用Connection接口进行开发,而基本上都是使用期子接口,子接口主要有:List、Set、Queue、SortedSet

Collection子接口的定义
在这里插入图片描述

1.1 List接口
Connection下分为很多的子接口,其中有一个List接口,List接口中可以存放任意的数据,而且在List接口中内容是允许重复的。
List接口的功能要比Collection接口强太多,因为大量扩充了Collection接口的操作
public interface List extends Collection

List接口的扩展方法
在这里插入图片描述

List接口的常用子类——ArrayList
在这里插入图片描述
如果想用接口,则肯定要使用对象的多态性进行实例化的操作,那么对于List接口本身也是一样的
ArrayList是List中最常用的子类

package Listdemo;

import java.util.ArrayList;
import java.util.List;

 public class ArrayListDemo01 {
public static void main(String[] args) {
	
	List<String> allList = new ArrayList<String>();		//制定操作的泛型为String
	allList.add("hello");		//此方法由Collection接口而来
	allList.add("world");		//默认情况下向最后加入
	System.out.println(allList);
	
}

}
运行结果:
[hello,world]

在指定位置添加,添加的方法是List接口扩充的方法
package Listdemo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class ArrayListDemo01 {
public static void main(String[] args) {
	
	List<String> allList = null;		
	Collection<String> allCollection = null;
	
	allList = new ArrayList<String>();		//制定操作的泛型为String
	allCollection = new ArrayList<String>();		//指定一个集合
	
	allList.add("hello");		//此方法由Collection接口而来
	allList.add(0,"world");		//在第一个位置添加world
	System.out.println(allList);
	
	allCollection.add("CZK");
	allCollection.add("www.baidu.com");
	
	allList.addAll(allCollection);
	
	System.out.println(allList);
	
}

}
运行结果:
[world, hello]
[world, hello, CZK, www.baidu.com]

package Listdemo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class ArrayListDemo01 {
public static void main(String[] args) {
	
	List<String> allList = null;		
	Collection<String> allCollection = null;
	
	allList = new ArrayList<String>();		//制定操作的泛型为String
	allCollection = new ArrayList<String>();		//指定一个集合
	
	allList.add("hello");		//此方法由Collection接口而来
	allList.add(0,"world");		//在第一个位置添加world
	System.out.println(allList);
	
	allCollection.add("CZK");
	allCollection.add("www.baidu.com");
	
	allList.addAll(allCollection);
	allList.addAll(0,allCollection);
	
	System.out.println(allList);
	
}

}
运行结果:
[world, hello]
[CZK, www.baidu.com, world, hello, CZK, www.baidu.com]

既然可以增加数据,那么也可以删除数据
*List中存在两种删除:根据对象内容,根据对象的编号

package Listdemo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class ArrayListDemo02 {
public static void main(String[] args) {
	List<String> allList = new ArrayList<String>();		//指定操作的泛型为String
	
	allList.add("Hello");		//此方法由Collection接口而来
	allList.add(0,"world");		//在第一个位置添加新的内容
	allList.add("MLDN");		//向Collection中加入内容
	allList.add("www.baidu.com");		
	
	allList.remove(0);	//删除第一个元素,删除指定的位置
	allList.remove("Hello");	//此方法由Collection接口继承而来
	
	System.out.println(allList);
}

}
运行结果:
[MLDN, www.baidu.com]

集合中的内容可以添加可以删除,那么实际上最重要的就是输出
*在List接口中提供了get()方法,利用此方法就可以完成输出
*通过循环完成输出,循环的次数由size()方法取得

package Listdemo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class ArrayListDemo03 {
public static void main(String[] args) {
	List<String> allList = new ArrayList<String>();		//指定操作的泛型为String
	
	allList.add("Hello");		//此方法由Collection接口而来
	allList.add("Hello");
	allList.add(0,"world");		//在第一个位置添加新的内容
	allList.add("MLDN");		//向Collection中加入内容
	allList.add("www.baidu.com");		
	
	System.out.print("由前向后输出:" );
	for(int i = 0;i < allList.size();i++) {
		System.out.print(allList.get(i) + "、");
	}
	
	System.out.println();
	
	System.out.print("由后向前和输出:");
	for(int i = allList.size() - 1;i >= 0;i--) {
		System.out.print(allList.get(i) + "、");
	}
}

}
运行结果:
由前向后输出:world、Hello、Hello、MLDN、www.baidu.com
由后向前和输出:www.baidu.com、MLDN、Hello、Hello、world、
此种输出方式是List接口所独有的,而其他接口是没有的,尤其是Collection中是没有根据索引取来内容的操作的。

package Listdemo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class ArrayListDemo04 {
public static void main(String[] args) {
	List<String> allList = new ArrayList<String>();		//指定操作的泛型为String
	
	allList.add("Hello");		//此方法由Collection接口而来
	allList.add(0,"world");		//在第一个位置添加新的内容
	allList.add("MLDN");		//向Collection中加入内容
	allList.add("www.baidu.com");		
	
	String str[] = allList.toArray(new String[] {} );		//指定好类型
	
	System.out.print("指定数组类型:" );
	for(int i = 0;i < str.length;i++) {
		System.out.print(str[i]+ "、");
	}
	
	System.out.print("\n返回对象数组:");
	Object obj[] = allList.toArray();		//返回Object类型
	for(int i = 0;i < obj.length;i++) {
		String temp = (String)obj[i];
		System.out.print(temp + "、");
	}
}

}
既然已经完成基本的输出功能,集合还有以下几种操作:
*判断集合是否为空:boolean isEmpty();
*截取部分集合:List subList(int fromIndex,int toIndex) List接口扩充
*查找指定的对象是否存在:int indexOf(Object o),如果查找到则返回位置,否则返回-1;
*查找是否存在:boolean contains(Object o)

package Listdemo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class ArrayListDemo05 {
public static void main(String[] args) { 
	List<String> allList = new ArrayList<String>();		//指定操作的泛型为String
	
	System.out.println("集合操作前是否为空?" + allList.isEmpty());
	
	allList.add("Hello");		//此方法由Collection接口而来
	allList.add(0,"world");		//在第一个位置添加新的内容
	allList.add("MLDN");		//向Collection中加入内容
	allList.add("www.baidu.com");		
	
	System.out.println(allList.contains("Hello") ?"\"Hello\"字符串存在!" : "\"Hello\"字符串不存在");
	
	List<String> allsub = allList.subList(2,3);
	System.out.println("集合截取:");
	for(int i = 0;i <allsub.size();i++) {
		System.out.println(allsub.get(i));
	}
	
	System.out.println("MLDN字符串的位置:" +allList.indexOf("MLDN"));
	System.out.println("集合操作前是否为空?" + allList.isEmpty());
}

}
运行结果:
集合操作前是否为空?true
"Hello"字符串存在!
集合截取:
MLDN
MLDN字符串的位置:2
集合操作前是否为空?false

1.2、LinkedList类
本章目标:
*掌握LinkedList与List接口的关系
*掌握Queue接口的作用

LinkedList子类与Queue接口
在这里插入图片描述

Queue接口定义的方法
在这里插入图片描述

LinkedList中操作链表的部分方法
在这里插入图片描述

本身带来那个扩充了Queue接口和List接口的操作。所以,在使用时最好直接使用LinkedList类完成操作。
为链表的开发和结尾增加数据

package linkedlistdemo;

import java.util.LinkedList;

public class LinkedListDemo01 {
public static void main(String[] args) {
	LinkedList<String> link = new LinkedList<String>();
	
	link.add("a");
	link.add("b");
	link.add("c");
	
	System.out.println("初始化链表:" +link);
	
	link.addFirst("X");		//在开头增加数据
	link.addLast("Y");		//在结尾增加数据
	System.out.println("增加开头和结尾之后的链表:" + link);
}

}
运行结果:
初始化链表:[a, b, c]
增加开头和结尾之后的链表:[X, a, b, c, Y]

对于链表也可以找到表头

package linkedlistdemo;

import java.util.LinkedList;

public class LinkedListDemo02 {
public static void main(String[] args) {
	LinkedList<String> link = new LinkedList<String>();
	
	link.add("a");
	link.add("b");
	link.add("c");
	
	System.out.println("1-1、element()方法找到表头:" +link.element());
	System.out.println("1-2、找完之后的链表内容:" + link);
	
	System.out.println("2-1、peek()方法找到表头:" +link.peek());
	System.out.println("2-2、找完之后的链表内容::" +link);
	
	System.out.println("3-1、poll()方法找到表头:" +link.poll());
	System.out.println("3-2、找完之后的链表内容:" +link);
	
}

}
运行结果:
1-1、element()方法找到表头:a
1-2、找完之后的链表内容:[a, b, c]
2-1、peek()方法找到表头:a
2-2、找完之后的链表内容::[a, b, c]
3-1、poll()方法找到表头:a
3-2、找完之后的链表内容:[b, c]

既然此类实现可Queue接口,那么来说就可以按照队列的方法进行先进先出的操作

package linkedlistdemo;

import java.util.LinkedList;

public class LinkedListDemo03 {
public static void main(String[] args) {
	LinkedList<String> link = new LinkedList<String>();
	
	link.add("a");
	link.add("b");
	link.add("c");
	
	System.out.print("以先进先出(FIFO)的方式输出:");
	for(int i = 0;i<=link.size() + 1;i++) {
		System.out.print(link.poll() + "、");
	}
}

}
运行结果:
以先进先出(FIFO)的方式输出:a、b、c、

1.3、Set接口
掌握Set接口与Collection接口的关系
掌握Set接口的常用子类:TreeSet、HashSet

Set接口的定义
在这里插入图片描述

HashSet:使用散列的方式存放内容,本身没有顺序

package setdemo;

import java.util.HashSet;
import java.util.Set;

public class HashSetDemo01 {
public static void main(String[] args) {
	Set<String> allSet = new HashSet<String>();
	allSet.add("A");	//增加内容
	allSet.add("B");	//增加内容
	allSet.add("C");	//增加内容
	allSet.add("C");	//重复内容
	allSet.add("C");	//重复内容
	allSet.add("D");	//增加内容
	allSet.add("E");	//增加内容
	
	System.out.println(allSet);
}

}
是无序排列的,而List接口的内容插入的顺序就是其保存的顺序。
如果现在希望所有的内容是可以自动进行排列的操作,则可以使用Set中的第二个子类 TreeSet

package setdemo;

import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo02 {
public static void main(String[] args) {
	Set<String> allSet = new TreeSet<String>();
	allSet.add("C");	//增加内容
	allSet.add("C");	//重复内容
	allSet.add("C");	//重复内容
	allSet.add("D");	//增加内容
	allSet.add("B");	//增加内容
	allSet.add("A");	//增加内容
	allSet.add("E");	//增加内容
	
	System.out.println(allSet);
}

}
运行结果:[A, B, C, D, E]
TreeSet子类是可以排序的

1.4 排序以及重复元素说明
掌握TreeSet的排序原理
掌握Set接口中重复元素的定义

举例:
import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo02 {
public static void main(String[] args) {

	Set<Person> allSet = new TreeSet<Person>();
	
	allSet.add(new Person("张三",30));
	allSet.add(new Person("李四",31));
	allSet.add(new Person("王五",32));
	allSet.add(new Person("王五",32));
	allSet.add(new Person("王五",32));
	allSet.add(new Person("赵六",33));
	allSet.add(new Person("孙七",33));
	
	System.out.println(allSet);
}

}

class Person {
private String name;
private int age;

public Person(String name,int age) {
	this.name = name;
	this.age = age;
}

public String getString() {
	return "姓名" + this.name + "年龄:" +this.age;
}

}
运行结果却出了错误:Exception in thread “main” java.lang.ClassCastException: setdemo02.Person cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(Unknown Source)
at java.util.TreeMap.put(Unknown Source)
at java.util.TreeSet.add(Unknown Source)
at setdemo02.TreeSetDemo02.main(TreeSetDemo02.java:11)

comparable主要是进行排序的操作接口,一个对象数组要想排序,则依靠comparable接口完成。那么对于TreeSet也一样,如果想要使用TreeSet进行排序的操作,则对象所在的类也必须实现comparable接口

import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo03 {	
public static void main(String[] args) {
	
	Set<Person01> allSet = new TreeSet<Person01>();
	
	allSet.add(new Person01("张三",30));
	allSet.add(new Person01("李四",31));
	allSet.add(new Person01("王五",32));
	allSet.add(new Person01("王五",32));
	allSet.add(new Person01("王五",32));
	allSet.add(new Person01("赵六",33));
	allSet.add(new Person01("孙七",33));
	
	System.out.println(allSet);
}

}

class Person01 implements Comparable<Person01>{
private String name;
private int age;

public Person01(String name,int age) {
	this.name = name;
	this.age = age;
}

public String toString() {
	return "姓名:" + this.name + ";年龄:" +this.age;
}

public int compareTo(Person01 per) { 
	if(this.age > per.age) {
		return 1;
	}else if(this.age < per.age){
		return -1;
	}else {
		return 0;
	}
}

}
运行结果:
[姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:王五;年龄:32, 姓名:赵六;年龄:33]

String类既然可以使用TreeSet排序,则String中肯定已经实现了comparable接口。但是结果有问题。发现此时去掉了重复的元素,但是依靠的是comparable完成的。孙七没有加入进来,因为孙七和赵六的年龄是一样的。comparable接口比较的只是年龄,所以为了保证正确,所有的属性都应该进行比较。

import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo03 {
public static void main(String[] args) {

	Set<Person01> allSet = new TreeSet<Person01>();
	
	allSet.add(new Person01("张三",30));
	allSet.add(new Person01("李四",31));
	allSet.add(new Person01("王五",32));
	allSet.add(new Person01("王五",32));
	allSet.add(new Person01("王五",32));
	allSet.add(new Person01("赵六",33));
	allSet.add(new Person01("孙七",33));
	
	System.out.println(allSet);
}

}

class Person01 implements Comparable{
private String name;
private int age;

public Person01(String name,int age) {
	this.name = name;
	this.age = age;
}

public String toString() {
	return "姓名:" + this.name + ";年龄:" +this.age;
}

public int compareTo(Person01 per) {
	if(this.age > per.age) {
		return 1;
	}else if(this.age < per.age){
		return -1;
	}else {
		return this.name.compareTo(per.name);
	}
}

}
运行结果:[姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:王五;年龄:32, 姓名:孙七;年龄:33, 姓名:赵六;年龄:33]

此时去掉的重复元素并不是真正意义上的重复元素取消。

import java.util.HashSet;
import java.util.Set;

public class TreeSetDemo03 {
public static void main(String[] args) {
	
	Set<Person01> allSet = new HashSet<Person01>();
	
	allSet.add(new Person01("张三",30));
	allSet.add(new Person01("李四",31));
	allSet.add(new Person01("王五",32));
	allSet.add(new Person01("王五",32));
	allSet.add(new Person01("王五",32));
	allSet.add(new Person01("赵六",33));
	allSet.add(new Person01("孙七",33));
	
	System.out.println(allSet);
}

}

class Person01{
private String name;
private int age;

public Person01(String name,int age) {
	this.name = name;
	this.age = age;
}

public String toString() {
	return "姓名:" + this.name + ";年龄:" +this.age;
}	

}
此时并没去掉重复的元素,那么重复的元素该如何取消呢?
如果取消重复的元素,则需要Object类中的两个方法帮助。
*hashcode:表示一个唯一的编码,一般通过计算表示。
*equal:进行对象的比较操作。

import java.util.HashSet;
import java.util.Set;

public class TreeSetDemo03 {
public static void main(String[] args) {
	
	Set<Person01> allSet = new HashSet<Person01>();
	
	allSet.add(new Person01("张三",30));
	allSet.add(new Person01("李四",31));
	allSet.add(new Person01("王五",32));
	allSet.add(new Person01("王五",32));
	allSet.add(new Person01("王五",32));
	allSet.add(new Person01("赵六",33));
	allSet.add(new Person01("孙七",33));
	
	System.out.println(allSet);
}

}

class Person01{
private String name;
private int age;

public Person01(String name,int age) {
	this.name = name;
	this.age = age;
} 

public String toString() {
	return "姓名:" + this.name + ";年龄:" +this.age;
}

public boolean equals(Object obj) {
	if(this == obj) {
		return true;
	}
	if(!(obj instanceof Person01)) {
		return false;
	}
	Person01 p = (Person01)obj;
	if(this.name.equals(p.name) && this.age == p.age) {
		return true;
	}else {
		return false;
	}
}
public int hashCode() {
	return this.name.hashCode() * this.age;
}

}
运行结果:[姓名:赵六;年龄:33, 姓名:王五;年龄:32, 姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:孙七;年龄:33]

1.5 SortedSet接口
掌握SortedSet接口与Set接口的关系
掌握SortedSet接口的常用操作方法

SortedSet接口定义
在这里插入图片描述

SortedSet接口中定义的方法
在这里插入图片描述

1.6、Iterator接口
*掌握集合输出的标准操作
*掌握Iterator接口的主要作用以及使用注意事项

在集合的操作中支持一下集中方式:
*Iterator
*ListIterator
*foreach输出
*Enumeration输出
Iterator接口简介
在这里插入图片描述
对于Iterator而言,因为其本身就是一个接口,所以想实例化必须依靠Collection接口完成。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class InteratorDemo01 {
public static void main(String[] args) {
	List<String> all = new ArrayList<String>();
	all.add("hello");
	all.add("_");
	all.add("world");
	
	Iterator<String> iter = all.iterator();  //为Interator接口实例化
	while(iter.hasNext()) {    //判断是否有内容
		System.out.println(iter.next());	//输出内容
	}
	
}

}
以上的操作代码属于Iterator的标准做法。
在Iterator接口中提供了remove方法,此方式是删除当前对象

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class InteratorDemo02 {
public static void main(String[] args) {
	List<String> all = new ArrayList<String>();
	all.add("hello");
	all.add("_");
	all.add("world");
	
	Iterator<String> iter = all.iterator();  //为Interator接口实例化
	while(iter.hasNext()) {		//判断是否有内容
		String str = iter.next();
		if("_".equals(str)) {
			iter.remove();
		}else {
			System.out.println(str);	//输出内容
		}
	}
	System.out.println("删除之后的集合:" + all);
}

}
运行结果:
hello
world
删除之后的集合:[hello, world]

在实际中Iterator是很少调用删除操作的,因为其本身的功能就是输出内容。当然,对于删除内容有一下注意点:
*List本身有删除操作
如果在使用迭代输出的过程中使用了List中的remove执行删除操作,则代码将出现问题。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class InteratorDemo03 {
public static void main(String[] args) {
	List<String> all = new ArrayList<String>();
	all.add("hello");
	all.add("_");
	all.add("world");
	
	Iterator<String> iter = all.iterator();  //为Interator接口实例化
	while(iter.hasNext()) {		//判断是否有内容
		String str = iter.next();
		if("_".equals(str)) {
			all.remove(str);
		}else {
			System.out.println(str);	//输出内容
		}
	}
	System.out.println("删除之后的集合:" + all);
}

}
运行结果:
hello
删除之后的集合:[hello, world]

在使用Iterator输出时,不要使用集合类中的remove方法,只能使用Iterator接口中的remove方法

总结:
*Iterator接口的功能是从前向后输出,属于单项输出
*Iterator的主要功能是完成迭代输出操作的
*在使用Iterator的时候最好不要删除数据

1.7、ListIterator接口
在这里插入图片描述

虽然此接口可以双向输出,但是Collection接口中并没有定义为此实例化的操作,只有List接口中才存在了ListIterator接口的实例化

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListIteratorDemo01 {
public static void main(String[] args) {
	List<String> all = new ArrayList<String>();
	
	all.add("Hello");
	all.add("_");
	all.add("world");
	
	ListIterator<String> iter = all.listIterator();
	System.out.print("由前向后输出:");
	while(iter.hasNext()) {
		String str = iter.next();
		System.out.print(str + "、");
	}
	System.out.println();
	System.out.print("由后向前输出:");
	while(iter.hasPrevious()) {
		String str = iter.previous();
		System.out.print(str + "、");
	}
}

}
运行结果:
由前向后输出:Hello、、world、
由后向前输出:world、
、Hello、

此时已经完成了双向输出,但是在使用此操作一定要注意一点:一定要先进行由前向后输出,之后才能进行由后向前输出。
使用ListIterator还可以进行增加和替换元素
*add()
*set()

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class ListIteratorDemo01 {
public static void main(String[] args) {
	List<String> all = new ArrayList<String>();
	
	all.add("Hello");
	all.add("_");
	all.add("world");
	
	ListIterator<String> iter = all.listIterator();
	System.out.print("由前向后输出:");
	while(iter.hasNext()) {
		String str = iter.next();
		System.out.print(str + "、");
		iter.set("LI - " + str);
	}
	System.out.println();
	System.out.print("由后向前输出:");
	iter.add("CZK");
	while(iter.hasPrevious()) {
		String str = iter.previous();
		System.out.print(str + "、");
	}
}

}
运行结果:
由前向后输出:Hello、_、world、
由后向前输出:CZK、LI - world、LI - _、LI - Hello、

总结:
1.如果想要使用ListIterator则只能依靠List接口完成
2.如果想要进行由后向前输出,则只能先进性右前向后输出
3.对于此接口中的增加及修改操作了解即可

1.7、foreach和Enumeration接口
掌握foteach对集合的输出支持
掌握Enumeration接口以及使用要求

import java.util.ArrayList;
import java.util.List;

public class ForeachDemo01 {
public static void main(String[] args) {
List all = new ArrayList();

	all.add("hello");
	all.add("_");
	all.add("world");
	
	for(String str:all) {
		System.out.println(str);
	}
}

}
运行结果:
hello
_
world

实际上Iterator属于一个新的输出口,在最早java刚出来的时候想法要输出的话,使用Enumeration接口完成输出
但是在java中因为存在发展的历史问题,所以有些地方好会使用Enumeration输出。而且必须注意的是,在使用Enumeration输出的时候一般都是直接操作Vector类完成的。

import java.util.Enumeration;
import java.util.Vector;

public class EnumerationDemo01 {
public static void main(String[] args) {
	Vector<String> all = new Vector<String>();
	
	all.add("hello");
	all.add("_");
	all.add("world");
	
	Enumeration<String> enu = all.elements();
	while(enu.hasMoreElements()) {   //判断是否有内容
		System.out.println(enu.nextElement());
	}
}

}
运行结果:
hello
_
world

总结:
1.在所有的输出操作中,以Iterator为最标准的输出操作,这一点始终要记住
2.在部分旧的操作中Enumeration仍然存在

1.8、Map接口
在这里插入图片描述

Collection的操作中之前发现,每次保存的对象都是一个对象,但是Map中保存的是一对对象,对象的形式是以:key-value的形式保存的
就好像电话本:张三->123456

Map接口
在这里插入图片描述

Map.Entry接口
在这里插入图片描述

Map.Entry接口的常用方法
在这里插入图片描述

Map与Map.Entry
在这里插入图片描述

Map接口的常用子类
在这里插入图片描述

以HashMap为例,说明Map的基本方法的操作:
import java.util.HashMap;
import java.util.Map;

public class HashMapDemo01 {
public static void main(String[] args) {
	Map<String,String> map = null;		//声明Map对象,其中key和value的类型为String
	map = new HashMap<String,String>();
	
	map.put("mldn", "www.mldn.com");
	map.put("chenzikang", "dashazi");
	map.put("mldnjava", "www.mldnjava.com");
	
	String val = map.get("mldn");		//根据key取出值
	System.out.println("取出的内容是:" + val);
}

}
运行结果:取出的内容是:www.mldn.com

在Map中也可以使用containsXxx()方法判断制定的key或者value存在

import java.util.HashMap;
import java.util.Map;

public class HashMapDemo02 {
public static void main(String[] args) {
	Map<String,String> map = null;		//声明Map对象,其中key和value的类型为String
	map = new HashMap<String,String>();
	
	map.put("mldn", "www.mldn.com");
	map.put("chenzikang", "dashazi");
	map.put("mldnjava", "www.mldnjava.com");
	
	if(map.containsKey("mldn")) {
		System.out.println("搜索的key存在!");
	}else {
		System.out.println("搜索的key不存在");
	}
	
	if(map.containsValue("www.mldn.com")) {
		System.out.println("搜索的value存在!");
	}else {
		System.out.println("搜索的value不存在");
	}
}

}
运行结果:
搜索的key存在!
搜索的value存在!

如果现在想输出全部的key,则使用如下方法:
Set keySet()

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class HashMapDemo03 {
public static void main(String[] args) {
	Map<String,String> map = null;		//声明Map对象,其中key和value的类型为String
	map = new HashMap<String,String>();
	
	map.put("mldn", "www.mldn.com");
	map.put("chenzikang", "dashazi");
	map.put("mldnjava", "www.mldnjava.com");
	 
	Set<String> keys = map.keySet();
	Iterator<String> iter = keys.iterator();
	while(iter.hasNext()) {
		String str = iter.next();
		System.out.println(str);
	}
}

}
运行结果:
mldn
chenzikang
mldnjava

既然可以输出全部的key,那么也可以输出全部的value。
Collection values()

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class HashMapDemo04 {
public static void main(String[] args) {
Map<String,String> map = null; //声明Map对象,其中key和value的类型为String
map = new HashMap<String,String>();

	map.put("mldn", "www.mldn.com");
	map.put("chenzikang", "dashazi");
	map.put("mldnjava", "www.mldnjava.com");
	 
	Collection<String> values = map.values();
	Iterator<String> iter = values.iterator();
	while(iter.hasNext()) {
		String str = iter.next();
		System.out.println(str);
	}
}

}
运行结果:
www.mldn.com
dashazi
www.mldnjava.com

在Map中也存在一个Hashtable子类,实际上这个子类的退出时间与Vector是一样的,都属于旧类

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class HashtableDemo01 {
public static void main(String[] args) {
	Map<String,String> map = null;		//声明Map对象,其中key和value的类型为String
	map = new HashMap<String,String>();
	
	map.put("mldn", "www.mldn.com");
	map.put("chenzikang", "dashazi");
	map.put("mldnjava", "www.mldnjava.com");
	
	Set<String> keys = map.keySet();
	Iterator<String> iter = keys.iterator();
	while(iter.hasNext()) {
		String str = iter.next();
		System.out.print(str + "、");
	}
	System.out.println();
	
	Collection<String> values = map.values();
	Iterator<String> iter01 = values.iterator();
	while(iter01.hasNext()) {
		String str = iter01.next();
		System.out.print(str + "、");
	}
}

}
运行结果:
mldn、chenzikang、mldnjava、
www.mldn.com、dashazi、www.mldnjava.com

HashMap与Hashtable的区别
在这里插入图片描述

在Map中还存在一个TreeMap的子类,此类也属于排序类,按key排序

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class TreeMapDemo01 {
public static void main(String[] args) {
	Map<String,String> map = null;
	map = new TreeMap<String,String>();
	
	map.put("A、mldn", "www.mldn.com");
	map.put("C、chenzikang", "dashazi");
	map.put("B、liuyadan", "xiaolanzhu");
	
	Set<String> keys = map.keySet();
	Iterator<String> iter = keys.iterator();
	while(iter.hasNext()) {
		String str = iter.next();
		System.out.println(str + "-->" + map.get(str));
	}
	
}

}
运行结果:
A、mldn–>www.mldn.com
B、liuyadan–>xiaolanzhu
C、chenzikang–>dashazi

使用TreeMap可以方便的完成排序的操作,如果自定义的类想要作为key的话,则肯定实现Comparable接口,指定比较的规则。

弱引用类:WeakHashMap
在这里插入图片描述
如果假设一个Map中的某些内容长时间不适用的话,按照之前的方法是不会删除的,如果希望可以自动删除,可以使用弱引用类。当里面 的某些内容不适用时,可以自动删除

import java.util.Map;
import java.util.WeakHashMap;

public class WeakHashMapDemo01 {
public static void main(String[] args) {
Map<String,String> map = null;
map = new WeakHashMap<String,String>();

	map.put(new String("mldn"),new String("www.mldn.com"));
	map.put(new String("czk"),new String("dsz"));
	map.put(new String("lyd"),new String("xlz"));
	
	System.gc();		//强制进行垃圾的收集操作
	System.out.println(map);
}

}

总结:
1.介绍了Map的特点及其基本操作
2.Map与Map.Entry的关系
3.Map的子类:HashMap、Hashtable、TreeMap、WeakHashMap
4.主要功能就是根据key找到value

1.9、Map接口的使用的注意事项
掌握Map接口的输出操作
掌握Map接口中key类的定义标准

Map接口输出
在这里插入图片描述
但是在操作前必须说明:Map接口一般只作为查找使用,输出的操作毕竟属于少数

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class IteratorDemo04 {
public static void main(String[] args) {
	Map<String,String> map = null;
	map = new HashMap<String,String>();
	
	map.put("mldn", "www.mldn.com");
	map.put("czk", "dashazi");
	map.put("lyd", "xiaolanzhu");
	
	Set<Map.Entry<String, String>> allset = null;
	allset = map.entrySet();
	
	Iterator<Map.Entry<String,String>> iter = null;
	iter = allset.iterator();
	
	while(iter.hasNext()) {
		Map.Entry<String, String> me = iter.next();
		System.out.println(me.getKey() + "-->" + me.getValue());
	}
}

}
运行结果:
czk–>dashazi
lyd–>xiaolanzhu
mldn–>www.mldn.com

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class ForeachDemo02 {
public static void main(String[] args) {
	Map<String,String> map = null;
	map = new HashMap<String,String>();
	
	map.put("mldn", "www.mldn.com");
	map.put("czk", "dashazi");
	map.put("lyd", "xiaolanzhu");
	
	for(Map.Entry<String, String> me:map.entrySet()) {
		System.out.println(me.getKey() + "-->" + me.getValue());
	}
}

}

这两种输出形式最终实际上还是以Collection的形式输出,只是以Map.Entry作为内容的操作类型

注意事项二:

在这里插入图片描述

在Map中,可以使用任意的类型作为key和value,那么使用非系统类可以

import java.util.HashMap;
import java.util.Map;

public class HashMapDemo05 {
public static void main(String[] args) {
	Map<String,Person> map = null;
	map = new HashMap<String,Person>();
	map.put("czk", new Person ("陈子康",21));
	System.out.println(map.get("czk"));
}

}

class Person{
private String name;
private int age;
public Person(String name,int age) {
	this.name = name;
	this.age = age;
}

public String toString() {
	return "姓名:" + this.name + ";年龄:" + this.age;
}

}
运行结果:姓名:陈子康;年龄:21

如果现在以String为key是可以取出内容的

import java.util.HashMap;
import java.util.Map;

public class HashMapDemo05 {
public static void main(String[] args) {
	Map<Person,String> map = null;
	map = new HashMap<Person,String>();
	map.put( new Person ("陈子康",21),"CZK");
	System.out.println(map.get( new Person ("陈子康",21)));
}

}

class Person{
private String name;
private int age;
public Person(String name,int age) {
	this.name = name;
	this.age = age;
}

public String toString() {
	return "姓名:" + this.name + ";年龄:" + this.age;
}

}
此时将自定义的类型为key,但是在取值的时候发现取不了,返回的结果是null。那么为什么之前的String可以但是自定义的类不存在呢?
实际上对于匹配的过程来讲,有一个特点,即:对象要一样才可以将内容查询出来。

import java.util.HashMap;
import java.util.Map;

public class HashMapDemo07 {
public static void main(String[] args) {
	Map<Person01,String> map = null;
	map = new HashMap<Person01,String>();
	Person01 per = new Person01("陈子康",21);
	map.put(per,"CZK");
	System.out.println(map.get(per));
}

}

class Person01{
private String name;
private int age;
public Person01(String name,int age) {
	this.name = name;
	this.age = age;
}

public String toString() {
	return "姓名:" + this.name + ";年龄:" + this.age;
}

}
这样可以取出内容
可是这样并不是解决问题的方法,因为不可能将Person的per对象带着到处走,应该像String一样,可以使用匿名对象的形式找到内容。那么此时实际上就需要与Set接口中判断重复元素的方式一样,进行方法的覆写。

import java.util.HashMap;
import java.util.Map;

public class HashMapDemo07 {
public static void main(String[] args) {
	Map<Person02,String> map = null;
	map = new HashMap<Person02,String>();
	map.put(new Person02("陈子康",21),"CZK");
	System.out.println(map.get(new Person02("陈子康",21)));
}

}

class Person02{
private String name;
private int age;
public Person02(String name,int age) {
	this.name = name;
	this.age = age;
}

public String toString() {
	return "姓名:" + this.name + ";年龄:" + this.age;
}
public boolean equals(Object obj) {
	if(this == obj) {
		return true;
	}
	if(obj instanceof Person) {
		return false;
	}
	Person02 p = (Person02)obj;
	if(this.name.equals(p.name) && this.age == p.age) {
		return true;
	}else {
		return false;
	}
}
public int hashCodee.hashCode() * this.age;
}

}
运行结果:CZK

作为key,或者更准确的说是作为对象的时候,实际上是依靠hashCode()和equals()来判断两个匿名的对象是否相等,这一点由系统内部自动完成。

总结
1.Map可以使用迭代输出
*map -> entrySet -> Set -> Iterator ->Map.Entry -> key和value
2.如果使用非系统类作为key,则一定保证覆写equals和hashCode方法,否则无效

2.0、IdentityHashMap类
了解IdentityHashMap的作用

具体内容
在正常的Map操作中,key本身不能够重复的

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
class Person11{
private String name;
private int age;

public Person11(String name,int age){
	this.name = name;
	this.age = age;
}

public boolean equals(Object obj) {
	if(this == obj) {
		return true;
	}
	if(!(obj instanceof Person11) ) {
		return false;
	}
	Person11 P = (Person11)obj;
	if(this.name.equals(P.name) && this.age == P.age) {
		return true;
	}else{
		return false;
	}
	
}

public int hashCode() {
	return this.name.hashCode() * this.age;
}

public String toString() {
	return "姓名:" + this.name + ";年龄:" + this.age;
}

}

public class IdentityHashMapDemo01 {
public static void main(String[] args) {
	Map<Person11,String> map= null;
	map = new HashMap<Person11,String>();
	map.put(new Person11("张三",30),"zhangsan01");
	map.put(new Person11("张三",30),"zhangsan02");
	map.put(new Person11("李四",31),"lisi");
	
	Set<Map.Entry<Person11,String>> allset = null;
	allset = map.entrySet();
	
	Iterator<Map.Entry<Person11,String>> iter = null;
	iter = allset.iterator();
	while(iter.hasNext()) {
		Map.Entry<Person11, String> me = iter.next();
		System.out.println(me.getKey() + "-->" + me.getValue());
	}
}

}
运行结果:
姓名:张三;年龄:30–>zhangsan02
姓名:李四;年龄:31–>lisi

使用HashMap操作的时候,key内容是不能重复的,如果现在希望key的内容可以重复,(指的重复是指两个对象的地址不一样key1 == key2)则要使用IdentityHashMap类。

import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
class Person11{
private String name;
private int age;

public Person11(String name,int age){
	this.name = name;
	this.age = age;
}

public boolean equals(Object obj) {
	if(this == obj) {
		return true;
	}
	if(!(obj instanceof Person11) ) {
		return false;
	}
	Person11 P = (Person11)obj;
	if(this.name.equals(P.name) && this.age == P.age) {
		return true;
	}else{
		return false;
	}
	
}

public int hashCode() {
	return this.name.hashCode() * this.age;
}

public String toString() {
	return "姓名:" + this.name + ";年龄:" + this.age;
}

}

public class IdentityHashMapDemo01 {
public static void main(String[] args) {
	Map<Person11,String> map= null;
	map = new IdentityHashMap<Person11,String>();
	map.put(new Person11("张三",30),"zhangsan01");
	map.put(new Person11("张三",30),"zhangsan02");
	map.put(new Person11("李四",31),"lisi");
	
	Set<Map.Entry<Person11,String>> allset = null;
	allset = map.entrySet();
	
	Iterator<Map.Entry<Person11,String>> iter = null;
	iter = allset.iterator();
	while(iter.hasNext()) {
		Map.Entry<Person11, String> me = iter.next();
		System.out.println(me.getKey() + "-->" + me.getValue());
	}
}

}
运行结果:
姓名:张三;年龄:30–>zhangsan01
姓名:张三;年龄:30–>zhangsan02
姓名:李四;年龄:31–>lisi

就算是两个对象的内容相等,但是因为都使用了new关键字,所以地址肯定不相等,那么就可以加入进去,key是可以重复的

总结
1.了解一下IdentityMap类的作用即可,在此类实际上是使用非常少的

2.1、SortedMap类
掌握SortedMap接口的作用

具体内容
回顾:SortedSet,是TreeSet的实现接口,那么此接口是可以排序的。
SortedMap也是排序的操作,之前学习过TreeMap类,此类是可以排序的。

SortedMap接口扩展的方法
在这里插入图片描述

import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

public class SortedMapDemo01 {
public static void main(String[] args) {
SortedMap<String,String> map = null;
map = new TreeMap<String,String>();

	map.put("D、chenzikang", "http://www.baidu.com");
	map.put("A、mldn", "http://www.mldn.com");
	map.put("C、liuyadan","http://www.asdfghjlk.com" );
	map.put("B、lanzhu", "http://www.lanzhu.com");
	System.out.print("第一个元素的内容的key:" + map.firstKey() );
	System.out.println(":对应的值:" + map.get(map.firstKey()));
	
	System.out.print("最后元素的内容的key:" + map.lastKey() );
	System.out.println(":对应的值:" + map.get(map.lastKey()));
	
	System.out.println("返回小于指定范围的集合:");
	for(Map.Entry<String,String> me : map.headMap("B、lanzhu").entrySet()) {
		System.out.println("\t |-" + me.getKey() +"-->" + me.getValue());
	}
	
	System.out.println("返回大于指定范围的集合:");
	for(Map.Entry<String,String> me : map.tailMap("B、lanzhu").entrySet()) {
		System.out.println("\t |-" + me.getKey() +"-->" + me.getValue());
	}
	
	System.out.println("部分集合:");
	for(Map.Entry<String, String> me: map.subMap("A、mldn","C、liuyadan").entrySet()) {
		System.out.println("\t|-" + me.getKey() + "-->" + me.getValue());
	}
}

}
运行结果:
第一个元素的内容的key:A、mldn:对应的值:http://www.mldn.com
最后元素的内容的key:D、chenzikang:对应的值:http://www.baidu.com
返回小于指定范围的集合:
|-A、mldn–>http://www.mldn.com
返回大于指定范围的集合:
|-B、lanzhu–>http://www.lanzhu.com
|-C、liuyadan–>http://www.asdfghjlk.com
|-D、chenzikang–>http://www.baidu.com
部分集合:
|-A、mldn–>http://www.mldn.com
|-B、lanzhu–>http://www.lanzhu.com

总结:
1.认识Map接口的子接口,SortedMap接口的基本概念。
2.此接口还有很多的操作方法
3.在实际中还是以Map接口为操作的标准。

2.2、Collection.wmv
掌握Collection与Collection接口的区别
掌握Collections类中提供的主要方法

具体内容:
在面试题中可能会有这样一个问题,请回答,Collection和Collections的关系
Collections与Collection没有直接的关系,但是与集合中的各个接口都有操作的方法支持。

Collections类的常用方法以及常量
在这里插入图片描述

验证:空集合的操作
*public static final List emptyList()
*public static final ListemptySet()

public class CollectionsDemo {
public static void main(String[] args) {
	List<String> alllist = Collections.emptyList();
	Set<String> allset = Collections.emptySet();
	
	alllist.add("Hello");
}

}
运行结果:Exception in thread “main” java.lang.UnsupportedOperationException
at java.util.AbstractList.add(Unknown Source)
at java.util.AbstractList.add(Unknown Source)
at collectionsdemo.CollectionsDemo.main(CollectionsDemo.java:12)
如果想要为集合中增加内容,则肯定使用add方法,在Collections中也提供了专门的增加操作。
public static boolean allAll(Collections<?super T>)
使用了可变参数,所以,可以任意输入各种类型的数据。

public class CollectionsDemo01 {
public static void main(String[] args) {
List alllist = new ArrayList();
Collections.addAll(alllist, “MLDN”,“CZK”,“MLDNJAVA”);
Iterator iter = alllist.iterator();

	while(iter.hasNext()) {
		System.out.print(iter.next() + "、");
	}
}

}
运行结果:
MLDN、CZK、MLDNJAVA、

猜你喜欢

转载自blog.csdn.net/weixin_43149344/article/details/83513562