JAVA笔记——集合框架
转载注明出处:https://blog.csdn.net/qq_40270579/article/details/81477036
目录
实线为为类,虚线为接口,Collections、Arrarys为工具类
集合:存储对象的容器
集合类的由来:
对象用来封装特有数据,对象多用来存储,如果对象的个数不确定就是用集合容器进行存储
集合特点:
1、用于存储对象的容器
2、集合的长度时可变的
3、集合中不可以存储基本数据类型值
集合框架因为内部的数据结构不同,有多种具体的容器
Collection
框架顶层Collection接口
Collection的常见方法:
1、增加
boolean add(E e);
boolean addAll(Collection c);
2、删除
boolean remove(E e);
boolean removeAll(Collection c); //删除指定集合中包含的所有此集合的元素(可选操作)。
void clear();
3、判断
boolean contains(Object obj);
boolean containsAll(Collection c); //如果此集合包含指定的元素,则返回true
boolean isEmpty(); //判断是否为空
4、获取
int size();
Iterator iterator(); //迭代器,取元素
5、其他
boolean retainAll(Collection c); //取交集
Object [] toArray(); //集合转数组
实例:
package com.collection;
import java.util.ArrayList;
import java.util.Collection;
/**
* 集合Collection的常见方法
* @author Administrator
*
*/
public class CollectionDemo {
public static void main(String[] args) {
Collection<String> c1 = new ArrayList<String>();
Collection<String> c2 = new ArrayList<String>();
show(c1);
show(c1,c2);
}
public static void show(Collection<String> c1,Collection<String> c2) {
//add
c1.add("abc1");
c1.add("abc2");
c1.add("abc3");
c2.add("abc5");
c2.add("abc2");
c2.add("abc6");
//addAll
c1.addAll(c2);
System.out.println("addAll操作后 c1:"+c1);
System.out.println("add操作后 c2:"+c2);
//containsAll
//此集合包含指定 集合中的所有元素,则返回true
//c2集合包含c1集合的所有元素,则返回true
boolean b2 = c1.containsAll(c2);
System.out.println("containsAll : "+b2);
//removeAll
//将两个集合中相同的元素从调用removeAll的集合中删除
//删除c1中与c2相同部分
boolean b1 = c1.removeAll(c2);
System.out.println("removeAll : "+b1);
System.out.println("c1:"+c1);
System.out.println("c2:"+c2);
//retainAll
//取交集,保留集合中相同的元素,与removeAll相反
//从c1集合中删除所有不包含在c2集合中的元素
boolean b3 = c1.retainAll(c2);
System.out.println("retainAll : "+b3);
System.out.println("c1:"+c1);
System.out.println("c2:"+c2);
}
public static void show(Collection<String> c) {
//1、添加元素
c.add("abc1");
c.add("abc2");
c.add("abc3");
System.out.println("remove删除前c : "+c);
//2、删除元素
c.remove("abc2");
System.out.println("remove删除后c : "+c);
System.out.println();
}
}
Iterator迭代器的使用
package com.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* 迭代器的使用
* @author Administrator
*
*/
public class IteratorDemo {
public static void main(String[] args) {
Collection<String> c = new ArrayList<String>();
c.add("abc1");
c.add("abc2");
c.add("abc3");
//迭代器iterator取元素
//方式一
System.out.println("while循环结构:");
Iterator it1 = c.iterator();
while(it1.hasNext()){
System.out.println(it1.next());
}
System.out.println("for循环结构:");
//方式二(开发使用,it使用后不再使用占内存,使用for循环创建的是临时变量,使用完后被释放)
for(Iterator it2 = c.iterator();it2.hasNext(); ){
System.out.println(it2.next());
}
System.out.println("直接输出结果:"+c);
}
}
迭代器原理:
通过内部类实现,该迭代器对象必须依赖于具体容器,因为每一种容器的数据结构都不同
所以迭代器对象是在容器中进行内部实现的。
Iterator接口就是对所有的Collection容器进行元素取出的公共接口
Collection
|--List:有序(存取的顺序一致),元素都有索引,元素可以重复
|--Set:元素不能重复,无序
List
列表集合
特有的常见方法:有一个共性特点,都可以操作角标
1、增加
void add(index,element);
void add(index,collection);
2、删除
Object remove(index);
3、修改
Object set(index,element);
4、获取
Object get(index);
int indexOf(Object);
int lastIndexOf(Object);
List subList(from,to);
List集合可以完成对元素的增删改查
例子:
package com.list;
import java.util.ArrayList;
import java.util.List;
/**
* List列表的特有方法
* @author Administrator
*
*/
public class ListDemo {
public static void main(String[] args) {
List list = new ArrayList();
show(list);
}
private static void show(List list) {
//添加
list.add("abc1");
list.add("abc2");
list.add("abc3");
System.out.println("list : "+list);
//插入
list.add(1,"abc6");
System.out.println("list : "+list);
//删除
System.out.println("remove(2) : "+list.remove(2));
//修改
System.out.println("set(1) : "+list.set(1,"abc5"));
//获取
System.out.println("get(0) : "+list.get(0));
//获取子列表
System.out.println("subList(1,2) : "+list.subList(1,2));
System.out.println("list : "+list);
}
}
List迭代器的使用
package com.list;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
* List迭代器的使用
* @author Administrator
*
*/
public class ListIteratorDemo {
public static void main(String[] args) {
List list = new ArrayList();
list.add("abc1");
list.add("abc2");
list.add("abc3");
list.add("abc4");
//Iterator it = list.iterator();
//可以实现在迭代过程中完成对数据的增删改查
//只有List集合具备该迭代器功能
ListIterator it = list.listIterator();
//正序输出
while(it.hasNext()){
Object obj = it.next();
if(obj.equals("abc2")){
it.set("abc6");
}
//在迭代器过程中,不能使用集合中操作数据,可以使用ListIterator接口迭代器操作数据
System.out.println("next:"+obj);
}
System.out.println("迭代器内替换abc2为abc6后:"+list);
//逆序输出
while(it.hasPrevious()){
System.out.println("Previous:"+it.previous());
}
//get输出
for(int i = 0;i<list.size();i++) {
System.out.println("get:"+list.get(i));
}
}
}
List 列表
|--Vector:内部是数组结构,是同步的。增删查都慢!
|--ArrayList:内部是数组数据结构,不同步,替代了Vector。查元素快
|--LinkedList:内部是链表数据结构,是不同步的。增删元素速度快。
Vector
例子:
package com.list;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
/**
* Vector
* @author Administrator
*
*/
public class VectorDemo {
public static void main(String[] args) {
Vector v = new Vector();
v.add("abc1");
v.add("abc2");
v.add("abc3");
v.add("abc4");
//与迭代器功能一样
Enumeration en = v.elements();
while(en.hasMoreElements()) {
System.out.println("nextElement : "+en.nextElement());
}
Iterator it = v.iterator();
while(it.hasNext()){
System.out.println("next : "+it.next());
}
}
}
LinkedList
package com.list;
import java.util.Iterator;
import java.util.LinkedList;
/**
* LinkedList
* @author Administrator
*
*/
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList link = new LinkedList();
link.add("abc1");
link.add("abc2");
link.add("abc3");
link.add("abc4");
//获取第一个元素
//System.out.println(link.getFirst());
//获取元素删除
//System.out.println(link.removeFirst());
/*//取完后集合为空
while(!link.isEmpty()) {
System.out.println(link.removeFirst());
}
*/
Iterator it = link.iterator();
while(it.hasNext()) {
System.out.println("LinkedList : "+it.next());
}
}
}
LinkedList模拟堆栈和队列(面试题)
package com.list;
import java.util.*;
/**
* LinkedList实现队列
* @author Administrator
*
*/
class MyQueue{
private LinkedList<Object> link;
MyQueue(){
link = new LinkedList<Object>();
}
public void myAdd(Object obj){
link.addLast(obj);
}
public Object myGet(){
return link.removeFirst();
}
public boolean isNull() {
return link.isEmpty();
}
}
package com.list;
import java.util.LinkedList;
/**
* LinkedList实现堆栈
* @author Administrator
*
*/
class MyStack{
private LinkedList<Object> link;
MyStack(){
link = new LinkedList<Object>();
}
public void myAdd(Object obj){
link.addFirst(obj);
}
public Object myGet(){
return link.removeFirst();
}
public boolean isNull() {
return link.isEmpty();
}
}
package com.list;
/**
* LinkedList模拟堆栈和队列
* 堆栈:先进后出(FILO) first in last out
* 队列:先进先出(FIFO) first in first out
* @author Administrator
*
*/
public class LinkedListTest {
public static void main(String[] args) {
//队列测试
MyQueue q = new MyQueue();
q.myAdd("abc1");
q.myAdd("abc2");
q.myAdd("abc3");
q.myAdd("abc4");
while(!q.isNull()) {
System.out.println("队列 : "+q.myGet());
}
System.out.println();
//堆栈测试
MyStack s = new MyStack();
s.myAdd("abc1");
s.myAdd("abc2");
s.myAdd("abc3");
s.myAdd("abc4");
while(!s.isNull()) {
System.out.println("堆栈 : "+s.myGet());
}
}
}
ArrayList集合存储自定义对象
package com.list;
/**
* 定义Person类
* @author Administrator
*
*/
public class Person {
private String name;
private String sex;
public Person(String name, String sex) {
super();
this.name = name;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
package com.list;
import java.util.*;
/**
* ArrayList集合存储自定义对象
* @author Administrator
*
*/
public class ArrayListDemo {
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) {
ArrayList a1 = new ArrayList();
a1.add(new Person("小 米","18"));
a1.add(new Person("小 白","19"));
a1.add(new Person("小煤球","19"));
a1.add(new Person("章 鱼","18"));
Iterator it = a1.iterator();
while(it.hasNext()) {
Person p = (Person) it.next();
System.out.println(p.getName()+"----"+p.getSex());
}
}
}
Set
Set :元素不重复,是无序的
Set接口与 Collection一致
Set
|--HashSet:内部结构是哈希表,不同步
|--TreeSet:
HashSet
package com.set;
import java.util.HashSet;
import java.util.Iterator;
/**
* HashSet
* @author Administrator
*
*/
public class HashSetDemo {
public static void main(String[] args) {
HashSet hs = new HashSet();
//元素不重复
hs.add("abc1");
hs.add("abc2");
hs.add("abc3");
hs.add("abc5");
hs.add("abc4");
Iterator it = hs.iterator();
while(it.hasNext()) {
//无序输出
System.out.println(it.next());
}
}
}
哈希表:
哈希表确定两个元素是否相同:
1、判断的是两个元素的哈希值是否相同,如果相同,再判断两个对象的内容是否相同
2、判断哈希值相同,使用的是hashCode方法。判断内容相同使用的是equals方法。
注:如果哈希值不同,则不需要判断equals
举例:对象的元素判断是否相同
//重写hashCode和equals方法
package com.list;
/**
* 定义Person类
* @author Administrator
*
*/
public class Person {
private String name;
private String sex;
private int age;
/**
* 自定义Person的hashCode方法
*/
@Override
public int hashCode() {
return name.hashCode()+age;
}
/**
* 自定义内容判断方法
*/
@Override
public boolean equals(Object obj) {
Person p = (Person)obj;
return this.name.equals(p.name)&&this.age == p.age;
}
public Person(String name, String sex) {
super();
this.name = name;
this.sex = sex;
}
public Person(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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
package com.set;
import java.util.HashSet;
import java.util.Iterator;
import com.list.Person;
/**
* 往HashSet里存储Person对象,判断如果年龄和姓名相同,视为同一元素
* @author Administrator
*
*/
public class HashSetTest {
public static void main(String[] args) {
HashSet hs = new HashSet();
//元素不重复
hs.add(new Person("张三1",18));
hs.add(new Person("张三4",19));
hs.add(new Person("张三3",28));
hs.add(new Person("张三2",20));
hs.add(new Person("张三5",17));
hs.add(new Person("张三6",38));
hs.add(new Person("张三3",28)); //测试
Iterator it = hs.iterator();
while(it.hasNext()) {
Person p = (Person) it.next();
System.out.println(p.getName()+"----"+p.getAge());
}
}
}
没有重写hashCode和equals方法的结果:
ArrayList练习:删除ArrayList中相同元素(普通变量、自定义对象)
package com.test;
import java.util.ArrayList;
import java.util.Iterator;
/**
* 删除ArrayList中相同元素(普通变量、自定义对象)
* @author Administrator
*
*/
public class ArrayListTest2 {
public static void main(String[] args) {
ArrayList<String> a = new ArrayList<String>();
a.add("abc1");
a.add("abc2");
a.add("abc2");
a.add("abc3");
a.add("abc4");
System.out.println("a :"+a);
a=getSignalElement(a);
System.out.println("a :"+a);
}
public static ArrayList getSignalElement(ArrayList a) {
//创建临时变量
ArrayList temp = new ArrayList();
//迭代集合a
Iterator it = a.iterator();
while(it.hasNext()) {
Object obj = it.next();
if(!temp.contains(obj)) {
temp.add(obj);
}
}
return temp;
}
}
自定义对象:
TreeSet
判断数据唯一性方式:
根据比家谱方法的返回结果是否为0,如果是,那么就是同一元素
TreeSet对元素进行排序的方式之一:
让元素自身具有比较功能,元素就需要实现Comparable接口,覆盖compareTo方法
如果不要按照对象中具备的自然排序。如果对象中不具备自然排序,该如何处理?
使用第二种排序方式:
让集合自身具有比较功能,定义一个类实现Comparator接口,覆盖compare方法,将该类对象作为参数传递给TreeSet集合的构造函数
package com.set;
import java.util.Iterator;
import java.util.TreeSet;
/**
* TreeSet(普通变量)
* @author Administrator
*
*/
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add("abc3");
ts.add("abc4");
ts.add("abc5");
ts.add("abc1");
ts.add("abc2");
Iterator it = ts.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
自定义对象:
package com.set;
import java.util.Iterator;
import java.util.TreeSet;
import com.list.Person;
/**
* TreeSet(自定义对象)
* @author Administrator
*
*/
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Person("张三",19));
ts.add(new Person("李四",18));
ts.add(new Person("王五",29));
ts.add(new Person("周六",19));
Iterator it = ts.iterator();
while(it.hasNext()) {
Person p = (Person) it.next();
System.out.println(p.getName()+"......"+p.getAge());
}
}
}
出现错误:com.list.Person cannot be cast to java.lang.Comparable
com.list.Person不能转换为java.lang.可比性
public interface Comparable<T>
该接口对实现它的每个类的对象强加一个整体排序。 这个排序被称为类的自然排序 ,类的compareTo方法被称为其自然比较方法 。
解决方法: 重写comparTo方法,扩展比较功能
package com.list;
/**
* 定义Person类
* @author Administrator
*
*/
public class Person extends Object implements Comparable{
private String name;
private String sex;
private int age;
/**
* 自定义Person的hashCode方法
*/
@Override
public int hashCode() {
return name.hashCode()+age;
}
/**
* 自定义内容判断方法
*/
@Override
public boolean equals(Object obj) {
Person p = (Person)obj;
return this.name.equals(p.name)&&this.age == p.age;
}
public Person(String name, String sex) {
super();
this.name = name;
this.sex = sex;
}
public Person(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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return name+":"+age;
}
//重写compareTo,实现对象的比较(此处为年龄)
public int compareTo(Object obj){
Person p = (Person)obj;
int temp = this.age-p.age;
return temp==0 ?this.name.compareTo(p.name):temp;
/*if(this.age>p.age){
return 1;
}
if(this.age<p.age){
return -1;
}
return this.name.compareTo(p.name);*/
}
}
package com.set;
import java.util.Iterator;
import java.util.TreeSet;
import com.list.Person;
/**
* TreeSet(自定义对象,重写compareTo,实现对象的比较)
* @author Administrator
*
*/
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Person("张三",19));
ts.add(new Person("李四",18));
ts.add(new Person("王五",29));
ts.add(new Person("周六",19));
//测试
ts.add(new Person("李四",18));
ts.add(new Person("王五",29));
Iterator it = ts.iterator();
while(it.hasNext()) {
Person p = (Person) it.next();
System.out.println(p.getName()+"......"+p.getAge());
}
}
}
比较器:
package com.set;
import java.util.Comparator;
import com.list.Person;
public class ComparatorByName implements Comparator {
@Override
/**
* 创建一个根据Person类姓名进行的比较器
*/
public int compare(Object o1, Object o2) {
Person p1 = (Person) o1;
Person p2 = (Person) o2;
int temp = p1.getName().compareTo(p2.getName());
return temp == 0?p1.getAge()-p2.getAge():temp;
}
}
package com.set;
import java.util.Iterator;
import java.util.TreeSet;
import com.list.Person;
/**
* TreeSet(对象排序,按照姓名排,构造比较器)
* @author Administrator
*
*/
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet(new ComparatorByName());
ts.add(new Person("zhangsan",19));
ts.add(new Person("lisi",18));
ts.add(new Person("wangwu",29));
ts.add(new Person("zhouliu",19));
//测试姓名相同,比较年龄
ts.add(new Person("lisi",28));
Iterator it = ts.iterator();
while(it.hasNext()) {
Person p = (Person) it.next();
System.out.println(p.getName()+"......"+p.getAge());
}
}
}
TreeSet二叉树:
public int compare(Object o1, Object o2) {
Person p1 = (Person) o1;
Person p2 = (Person) o2;
int temp = p1.getName().compareTo(p2.getName());
return temp == 0?p1.getAge()-p2.getAge():temp;
}
比较器返回值:
左孩子:-1(左小)
右孩子:1(右大)
练习:按照字符串长度排序
public int compare(Object o1, Object o2) {
String s1 = (String) o1;
String s2 = (String) o2;
int temp = s1.length()-s2.length();
return temp == 0?s1.compareTo.s2:temp;
}
-----------------------------------------------------------------
Map
顶层接口,一次添加一对元素,也成为双列集合,Collection为单列集合
Map存储键值对,必须保证键的唯一性
常用方法:
1、添加
void put(key,value);返回抢一个和key关联的值,如果没有则返回null
2、删除
void clear();清空map集合
void remove(key);根据指定的key移除这个键值对
3、判断
boolean containsKey(key);
boolean containsValue(value);
boolean isEmpty();
4、获取
value get(key); 通过键获取值,没有键返回null
int size(); 返回键值对的个数
package com.map;
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap();
methon(map);
}
public static void methon(Map<Integer,String> map) {
//添加元素
//存相同键值会覆盖
System.out.println(map.put(8, "二狗"));//null
System.out.println(map.put(8, "八狗"));//二狗
map.put(2, "二狗");
map.put(7, "七狗");
map.put(4, "四狗");
map.put(6, "六狗");
//删除
System.out.println("remove(2):"+map.remove(2));
//判断
System.out.println("containsKey(7):"+map.containsKey(7));
//获取
System.out.println("get(6):"+map.get(6));
System.out.println(map);
}
}
/**
* 获取map中全部的元素
* 原理:通过keySet方法获取map中所有键所在的Set集合,通过Set迭代器获取每一个键值
* 再通过get(key)方法得到value
* @param map
*/
public static void methon_2(Map<Integer,String> map) {
map.put(2, "二狗");
map.put(7, "七狗");
map.put(4, "四狗");
map.put(6, "六狗");
Set<Integer> keySet = map.keySet();
Iterator<Integer> it = keySet.iterator();
while(it.hasNext()) {
Integer key = it.next();
String value = map.get(key);
System.out.println(key+" = "+value);
}
}
/**
* 通过map转换成Set即可迭代
* 第二中方法:entrySet
* 该方法通过将键和值的映射关系作为对象存储到Set集合
* Set<Map.Entry<K,V>> entrySet()
* @param map
*/
public static void methon_3(Map<Integer,String> map) {
map.put(2, "二狗");
map.put(7, "七狗");
map.put(4, "四狗");
map.put(6, "六狗");
Set<Map.Entry<Integer, String>> entrySet = map.entrySet();
Iterator<Map.Entry<Integer, String>> it = entrySet.iterator();
while(it.hasNext()) {
Map.Entry<Integer, String> me = it.next();
int key = me.getKey();
String value = me.getValue();
System.out.println(key+" = "+value);
}
}
原理:
methon_2
methon_3
TreeMap
与HashMap类似
LinkedHashMap
package com.map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
/**
*
* @author Administrator
*
*/
public class LinkedHashMapDemo {
public static void main(String[] args) {
//HashMap<Integer,String> hm = new HashMap<Integer,String>();
HashMap<Integer,String> hm = new LinkedHashMap<Integer,String>();
//LinkedHashMap,怎么存入怎么取出
//HashMap,已排序取出
hm.put(2, "二狗");
hm.put(5, "五狗");
hm.put(4, "四狗");
hm.put(8, "八狗");
hm.put(6, "六狗");
Iterator<Map.Entry<Integer,String>> it = hm.entrySet().iterator();
while(it.hasNext()) {
Map.Entry<Integer,String> me = it.next();
Integer key = me.getKey();
String value = me.getValue();
System.out.println(key+"......"+value);
}
}
}
LinkedHashMap结果
HashMap结果
Map集合练习:
记录字母次数
对与结果分析发现,字母和次数之间存在映射关系
能够存储映射关系的容器有数组和Map集合
关系方式无序可以考虑Map集合,又发现输出的结果有序,所以使用TreeMap
package com.test;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
/**
* 获取字符串中每个字符串出现的次数
* 打印输出:a(1)b(2)...
* 1、因为操作的是字符串中的字母,所以先将字符串转为字符数组
* 2、遍历数组,用一个字母作为键去查Map集合表
如果该字母键不存在,将该字母作为键,1作为值存储到map集合中
如果该字母键存在,将该字母键取出并+1储到map集合中
键相同值会覆盖
* 3、遍历结束,map集合就记录了所有字母出现的次数
* @author Administrator
*
*/
public class MapTest {
public static void main(String[] args) {
String str = "axnaj --=jnccka";
String s = getStrCount(str);
System.out.println(s);
}
public static String getStrCount(String str) {
//将字符串转字符数组
char[] chs = str.toCharArray();
//定义Map集合表
Map<Character,Integer> map = new TreeMap();
for (int i = 0; i < chs.length; i++) {
//当含有其他非字母字符是进行判断countine
if(!(chs[i]>='A'&&chs[i]<='Z'||chs[i]>='a'&&chs[i]<='z'))
continue;
//将数组中的字母作为键取查map表
Integer value = map.get(chs[i]);
int count = 1;
//判断是否为空
if(value!=null) {
count = value+1;
}
map.put(chs[i], count);
/*if(value == null) {
map.put(chs[i],1);
}else {
map.put(chs[i],value+1);
} */
}
return mapToString(map).toString();
}
private static StringBuffer mapToString(Map<Character, Integer> map) {
StringBuffer sb = new StringBuffer();
Iterator<Character> it = map.keySet().iterator();
while(it.hasNext()) {
Character key = it.next();
Integer value = map.get(key);
sb.append(key+"("+value+")");
}
return sb;
}
}
结果:
Map查表法
package com.test;
import java.util.HashMap;
import java.util.Map;
/**
* 输入数字输出星期
* @author Administrator
*
*/
public class MapTest2 {
public static void main(String[] args) {
// Map在有映射关系时,优先考虑, Map查表法较为常见
String week = getWeek(1);
System.out.println(week);
System.out.println(getWeekByMap(week));
}
private static String getWeekByMap(String week) {
Map<String,String> map = new HashMap<String,String>();
map.put("星期一", "Monday");
map.put("星期二", "Tuesday");
map.put("星期三", "Wednesday");
map.put("星期四", "Thursday");
map.put("星期五", "Friday");
map.put("星期六", "Saturday");
map.put("星期日", "Sunday");
map.put("星期天", "Sunday");
return map.get(week)==null?"无对应星期!":map.get(week);
}
private static String getWeek(int week) {
if(week<1||week>7) {
throw new RuntimeException("没有对应星期!");
}
String []weeks = {"","星期一","星期二","星期三","星期四","星期五","星期六","星期天"};
return weeks[week];
}
}
泛型
JDK5出现的安全机制,
好处:
1、将运行十七的问题ClassCastException转到编译时期
2、避免了强制转换的麻烦
<>什么时候使用?当操作的引用数据类型不确定的时候
用于接收具体引用数据类型的参数范围
在程序中,只要用到了带有<>的类或接口,就要明确传入的具体引用数据类型
泛型技术是给编译器使用的技术,用与编译时期,确保类型的安全性
擦除&补偿
运行时,会将泛型去掉,生成的class文件中不带泛型,这个叫泛型的擦除
为什么擦除?因为为了兼容运行的类加载器。
运行时,通过获取元素进行转换动作,不用使用者进行操作。
泛型在集合中的应用:
package com.generic;
import java.util.Iterator;
import java.util.TreeSet;
import com.test.Person;
/**
* 泛型的使用
* @author Administrator
*
*/
public class GenericDemo {
public static void main(String[] args) {
TreeSet<Person> ts = new TreeSet<Person>();
ts.add(new Person("小 米",18));
ts.add(new Person("小 白",19));
ts.add(new Person("小煤球",19));
ts.add(new Person("章 鱼",18));
Iterator<Person> it = ts.iterator();
while(it.hasNext()) {
Person p = (Person) it.next();
System.out.println(p.getName()+"----"+p.getAge());
}
}
}
泛型类
package com.generic;
/**
* 泛型类
* @author Administrator
*
* @param <Node>
*/
public class Tool<Node> {
private Node n;
public Tool() {
super();
}
public Tool(Node n) {
super();
this.n = n;
}
public Node getN() {
return n;
}
public void setN(Node n) {
this.n = n;
}
}
package com.generic;
public class GenericClassDemo {
public static void main(String[] args) {
Tool<String> str = new Tool<String>();
str.setN("haha");
System.out.println("String:"+str.getN());
Tool<Integer> a = new Tool<Integer>();
a.setN(66);
System.out.println("Integer:"+a.getN());
}
}
泛型方法
/**
* 将泛型定义在方法上
*/
public <W> void show(W str){
System.out.println("show:"+str);
}
/**
* 当方法为静态时,不能访问类上定义的的泛型。如果静态方法使用泛型,只能将泛型定义在方法上
*/
public static <Y> void method(Y obj){
System.out.println("method:"+str);
}
泛型接口:
interface Inter<T>{
public void show(T t);
}
class InterImpl <T> implements Inter<>{
public void show(T t){
System.out.println("show:"+t);
}
}
泛型限定
泛型的通配符:?
/**
* 迭代并打印集合中元素
*/
public static void printCollection(Collection<?> a){
Iterator<?> it = a.iterator();
while(it.hasNext()){
//重写toString方法,可以指定输出格式
System.out.println(it.next().toString());
}
}
//限定为Person的子类,Person为上限
/**
* 迭代并打印集合中元素
* ? extends E 接受E类型或者E类型的子类
*
*/
public static void printCollection(Collection<? extends Person> a){
Iterator<? extends Person> it = a.iterator();
while(it.hasNext()){
Person p = it.next();
System.out.println(p.getName()+" "+p.getAge);
}
}
上限的体现:
//? super E 接受E类型或者E类型的父类类
public static void printCollection(Collection<? super Student> a){
Iterator<? super Student> it = a.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
集合查阅技巧
需要唯一吗?
需要:Set
需要有序吗?
需要:TreeSet
不需要:HashSet
和存储一致的顺序:LinkedHashSet
不需要:List
需要频繁增删吗?
需要:LinkedList
不需要:ArrayList
如何记录每一个容器的结构和所属体系?
List:
|--ArrayList
|--LinkedList
Set:
|--HashSet
|--TreeSet
后缀名就是该集合所属的体系
前缀名就是该集合的数据结构
Array:数组,查询快,有角标
Link:链表,增删快,add\get\remove\first\list
hash:哈希表,唯一性,元素覆盖hashCode方法和equals方法
tree:二叉树,排序,两个接口Comparable,Comparator
而且通常这些常用的集合容器都是不同步的。
工具类
Collections工具类
package com.collections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.TreeSet;
/**
* Collections工具类
* @author Administrator
*
*/
public class CollectionsDemo {
public static void main(String[] args) {
sortDemo();
}
public static void sortDemo() {
List<Integer> list = new ArrayList<Integer>();
list.add(40);
list.add(32);
list.add(10);
list.add(132);
list.add(82);
list.add(3);
System.out.println("list:"+list);
//排序
Collections.sort(list);
System.out.println("sort:"+list);
//二分查找
int index = Collections.binarySearch(list, 32);
System.out.println("binarySearch:" +index);
//最值
System.out.println("max:"+Collections.max(list));
System.out.println("min:"+Collections.min(list));
//逆转reverseOrder,返回一个比较器,作为构造函数参数传入
System.out.println("reverseOrder:"+reverseOrderD());
}
//泛型使用
public static <T extends Comparable<? super T>> void MySort(List<T> list) {
for(int i = 0;i<list.size()-1;i++) {
for(int j = i+1;j<list.size();j++) {
if(list.get(i).compareTo(list.get(j))>0) {
/*T temp = list.get(i);
list.set(i,list.get(j));
list.set(j,temp);*/
//替换
Collections.swap(list, i, j);
}
}
}
}
public static TreeSet<Integer> reverseOrderD() {
TreeSet<Integer> ts = new TreeSet<Integer>(Collections.reverseOrder());
ts.add(40);
ts.add(32);
ts.add(10);
ts.add(132);
ts.add(82);
ts.add(3);
return ts;
}
}
Arrays工具类
package com.collections;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Arrays工具类
* @author Administrator
*
*/
public class ArraysDemo {
public static void main(String[] args) {
//数组转集合
System.out.println("数组转集合");
asListD();
//集合转数组
System.out.println("集合转数组");
ToArray();
}
/**
* 重点:数组转集合asList
* 好处:可以使用集合的方法操作数组的元素
* 注意:数组的长度是固定的,不可以使用集合的增删方法,否则会发生异常
* 如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储
* 如果数组的元素是基本数据类型,那么会将该数组作为集合的元素进行存储,使用包装类即可
*/
public static void asListD() {
//包装类
Integer []arr = {21,3,1,554,64,75,86,98};
List<Integer> arrlist = Arrays.asList(arr);
System.out.println(arrlist);
System.out.println("contains(32):"+arrlist.contains(32));
String []str = {"abc1","abc2","abc3","abc4","abc5"};
List<String> list = Arrays.asList(str);
System.out.println(list);
System.out.println("contains(abc4):"+list.contains("abc4"));
}
/**
* 集合转数组:使用Collection接口中的toArray方法,可以对集合中的元素的操作方法进行限定
* 不允许对其进行增删
*
*/
private static void ToArray() {
List<String> list = new ArrayList<String>() ;
list.add("abc3");
list.add("abc2");
list.add("abc1");
System.out.println(list);
/**
* toArray方法需要传入一个指定类型的数组
* 长度该如何确认?
* 如果长度小于集合的size,那么该方法会创建一个同类型并和集合相同size的数组
* 如果长度大于集合的size,那么该方法就会使用指定数组,存储集合中的数据元素,其他默认为null
* 建议指定长度为集合的size
*/
String []arr = list.toArray(new String[list.size()]);
System.out.println(Arrays.toString(arr));
}
//toString的经典实现(源码分析)
public static String MytoString(int[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; ; i++) {//中间省略条件判断,提高效率
b.append(a[i]);
if (i == iMax) //当i达到长度时,添加]结束
return b.append(']').toString();
b.append(", "); //否则添加", "
}
}
}
JDK5.0特性
ForEach循环
package com.test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* foreach语句
* @author Administrator
*
*/
public class ForEachDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("abc1");
list.add("abc3");
list.add("abc4");
list.add("abc2");
System.out.println("foreach语句:");
for(String s:list) {
System.out.println(s);
}
System.out.println("\nIterator语句:");
Iterator<String> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
//高级for遍历map
Map<Integer,String> map = new HashMap<Integer,String>();
map.put(1, "狗子");
map.put(2, "二狗");
map.put(3, "三狗");
map.put(4, "四狗");
map.put(5, "五狗");
map.put(6, "六狗");
System.out.println("\nkeySet:");
for (Integer key : map.keySet()) {
String value = map.get(key);
System.out.println(key+"......"+value);
}
System.out.println("\nentrySet:");
for (Map.Entry<Integer, String> me : map.entrySet()) {
String value = me.getValue();
Integer key = me.getKey();
System.out.println(key+"......"+value);
}
}
}
函数可变参数
package com.test;
/**
* 函数的可变参数
* @author Administrator
*
*/
public class ParamterDemo {
public static void main(String[] args) {
int[]arr = {1,5,321,3,112};
System.out.print("arr:");
for(int i:arr) {
System.out.print(i+" ");
}
System.out.println("\nadd(arr):"+add(arr));
}
/**
* 函数的可变参数
* 其实就是一个数组,但是接受的是数组的元素
* 自动将元素封装成数组
* 可变参数只能在参数列表的结尾
* @param arr
* @return
*/
private static int add(int ... arr) {
int sum = 0;
for(int i = 0;i<arr.length;i++) {
sum+=arr[i];
}
return sum;
}
}
静态导入
package com.test;
import java.util.ArrayList;
import java.util.List;
import static java.util.Collections.sort; // 静态导入类中的内容
/**
* 静态导入
* @author Administrator
*
*/
public class StaticImportDemo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(31);
list.add(20);
list.add(3);
list.add(91);
list.add(65);
System.out.println("list:");
System.out.println(list);
System.out.println("静态方法导入:");
//Collections.sort(list);
//import static java.util.Collections.sort;
sort(list);
System.out.println(list);
}
}
-------衣带渐宽终不悔,为伊消得人憔悴