黑马程序员_java 集合框架
Java集合概述:
为了保存数量不确定的数据,以及保存具有映射关系的数据,Java提供了集合类,也被称为容器。所有的集合类
都位于java.util包下。
集合类和数组的区别:
数组元素既可以是基本数据类型的数据,也可以是引用数据类型的数据。而集合里只能存储引用数据类型。
数组一旦定义后,长度不可变。而集合的长度会自动变化。
数组定义成什么类型,就只能存储什么类型的数据。而集合可以存储不同类型的对象
注意:集合和数组一样,都是存的对象的引用(地址)。
Java的集合类主要由两个接口派生而出:
Collection和Map是Java集合框架的根接口。
Collection(接口):
|--List(接口)
|--ArrayList :底层数据结构使用的是数组结构;默认长度是10,当超过10,它会new一个新的数组,50%延长,
然后把原来数组中的元素Copy到新数组中来,在把新元素添加到后面去
特点:查询速度快,但是增删慢,线程不同步,不安全,可变长度数组。
|--LinkedList :底层数据结构使用的是链表结构;
特点:查询速度慢,增删快
|--Vector:底层数据结构使用的是数组数据结构;默认长度也是10,当超过10,100%延长
特点:线程同步,安全,增删和查询都慢,可变长度数组,比较浪费空间。被ArrayList替代了
|--Set(接口):
元素是无序的(排列顺序可能与添加顺序不同),不允许存在重复元素,底层是Map集合
|--HashSet:底层数据结构是哈希表。线程不同步,不安全
HashSet是如何保证元素的唯一性的呢?
通过hashCode()和equals()方法。
如果元素的hashCode值相等,再判断equals;如果元素的hashCode不等,则不会调用equals()方法
|--TreeSet:可以对Set集合中元素进行排序,底层数据结构是二叉树
TreeSet是如何保证元素的唯一性的呢?
第一种方式:集合中的元素对象的类实现Comparable接口,重写compareTo(Object obj)
第二种方式:让TreeSet本身具备比较性,通过TreeSet的构造器,传入一个比较器对象Comparator,
并重写compare(Object obj1, Object obj2)方法
通过compareTo(Object obj)或compare(Object obj1, Object obj2)返回0,表示重复元素
Map:
|--Hashtable:JDK1.0出现。底层数据结构是hash表,不可以存入null键null值,线程同步,安全,效率低
|--HashMap:JDK1.2出现。底层数据结果是hash表,允许使用null键null值,线程不同步,不安全,效率高
|--TreeMap:底层是二叉树数据结果,线程不同步,可以用于给Map集合中的键进行排序
为什么会出现这么多容器?
因为每一个容器对数据的存储方式不同。这种存储方式成为数据结构
Collection:
Collection接口是List、Set、Queue的父接口。该集合定义的方法既可以操作List集合,也可以操作Set集合和Queue集合。
常见方法:
boolean add(Object obj):该方法向集合添加一个元素。添加成功,返回true
boolean addAll(Collection c):把c集合中的所有元素添加到集合中。只要有一个添加成功,返回true
void clear():清空集合里的所有元素
boolean remove(Object obj):删除集合中的元素,删除成功,返回true
boolean removeAll(Collection c):从集合中删除c集合里包含的元素,只要删除一个,返回true
boolean retainAll(Collection c):从集合中删除c集合里不包含的元素,取交集,如果改变了原集合,返回true
boolean contains(Object obj):查询集合里是否包含指定元素
boolean containsAll(Collection c):查询集合里是否包含c集合里的所有元素
boolean isEmpty():判断集合是否为空,如果长度为0,返回true
int size():返回集合中元素的个数
Object[] toArray():把集合转换成一个数组
Iterator iterator():返回一个Iterator迭代器对象,用于遍历集合元素
方法测试:
package com.itheima.collection;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionTest {
public static void main(String[] args) {
//创建集合对象
Collection c1 = new ArrayList();
//添加元素
c1.add("黑马程序训练营");
c1.add("JavaEE+Androd");
c1.add("JavaEE+物联云计算");
//虽然集合里不能放基本数据类型的数据,但Java支持自动装箱
c1.add(3);
Collection c2 = new ArrayList();
c2.add("haha");
c2.add("hehe");
c2.add("xixie");
//打印原集合,Collection的实现类都重写了toString()方法,该方法可以一次性的输出集合中的元素
System.out.println("c1集合中的元素:" + c1);
System.out.println("c2集合中的元素:" + c2);
//把c2集合中的元素添加到c1集合中
c1.addAll(c2);
System.out.println("添加后的c1集合:" + c1);
System.out.println("c2集合中的元素:" + c2);
//返回false,该方法只能删除元素,不能删除集合
System.out.println("是否删除成功:" + c1.remove(c2));
//删除指定元素
System.out.println("是否删除成功:" + c1.remove("haha"));
//查询c1集合是否包含c2集合中所有的元素
System.out.println("是否包含" + c1.containsAll(c2));
//查寻c1集合删除c2集合中不包含的元素
System.out.println("是否删除成功:" + c1.retainAll(c2));
//查询c1集合中的元素个数
System.out.println("c1集合中的元素个数:" + c1.size());
}
}
使用Iterator接口遍历集合元素
Iterator接口也是Java集合框架的成员,Iterator对象被称为迭代器,但Iterator仅用于遍历(迭代)集合元素,
不具备盛装数据的能力,如果需要创建Iterator对象,则必须有一个被迭代的集合,依附于Collection对象。
当使用Iterator迭代访问Collection集合元素时,集合元素不能被改变,只能通过Iterator的remove()方法删除
元素,否则将会引发ConcurrentModificationException异常
Iterator接口中的方法:
boolean hasNext():如果被迭代的集合元素还没有被遍历,返回true
boolean next():返回集合里的下一个元素
void remove():删除集合里上一次next()方法返回的元素
案例体现:
package com.itheima.collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class IteratorTest {
public static void main(String[] args) {
Collection c1 = new ArrayList();
//添加元素
c1.add("黑马程序训练营");
c1.add("JavaEE+Androd");
c1.add("JavaEE+物联云计算");
c1.add("haha");
//获取迭代器对象
/*
* 方式一:
* */
for(Iterator it = c1.iterator(); it.hasNext();)
{
String str = (String)it.next();
if("haha".equals(str))
{
//c1.remove(str);//引发异常
it.remove();
}
//这里依然会打印出haha,但是haha已经不存在于集合中
System.out.println(str);
}
/*
* 方式二:
* */
Iterator i = c1.iterator();
while(i.hasNext())
{
System.out.println(i.next());
}
方式三:
/*
* 使用foreach迭代中,集合也不能被改变
*/
for(Object obj : c1)
{
String str = (String)obj;
if("haha".equals(str))
//也将引发上述异常
c1.remove(str);
}
}
}
List集合:
集合中元素是有序的,允许使用重复元素,可以通过索引来访问集合中的元素。List集合默认按元素的添加顺序设置元素的索引。
因为List集合是有序集合,因此List集合增加了一些根据索引来操作集合元素的方法
常见方法:
void add(int index, Object element):将元素插入到List集合的index处
boolean addAll(int index, Collection c):将集合c中所有的元素,插入到List集合的index处
Object get(int index):根据索引获取元素
int indexOf(Object obj):返回对象o在集合中第一次出现的位置
int lastIndexOf(Object obj):返回对象o在集合中最后一次出现的位置
Object remove(int index):删除并返回index位置的元素
Object set(int index, Object element):将指定位置的元素修改成element对象,返回新元素
List subList(int fromIndex, int toIndex):返回从fromIndex(包含)到toIndex(不包含)的子集合,不会改变原集合
方法测试:
package com.itheima.list;
import java.util.ArrayList;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
List l1 = new ArrayList();
l1.add("黑马程序训练营");
l1.add("JavaEE+Androd");
l1.add("JavaEE+物联云计算");
l1.add("haha");
List l2 = new ArrayList();
l2.add("真的很不错");
l2.add("我也要去");
//向l1集合0索引位置插入元素
l1.add(0, "中关村");
//把l2集合中的元素添加到l1集合的元素的末尾
l1.addAll(l1.size(), l2);
//查询黑马程序训练营出现的位置
System.out.println(l1.indexOf("黑马程序训练营"));
//截取子集合
List l3 = l1.subList(2, 4);
}
}
使用ListIterator进行迭代:
ListIterator接口继承了Iterator接口,提供了专门操作List集合的方法。ListIterator在Iterator的基础之上增加了几个方法:
boolean hasPrevious():返回该迭代器关联的集合是否还有上一个元素
Object previous():返回该迭代器的上一个元素。
void add():在指定位置插入元素。
代码体现:
package com.itheima.list;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListIteratorTest {
public static void main(String[] args) {
List l1 = new ArrayList();
l1.add("黑马程序训练营");
l1.add("JavaEE+Androd");
l1.add("JavaEE+物联云计算");
l1.add("haha");
l1.add("haha");
ListIterator li = l1.listIterator();
System.out.println(li.hasPrevious());//输出false
while(li.hasNext())
{
String str = (String)li.next();
if("黑马程序训练营".equals(str))
li.add("联手CSDN");
}
System.out.println(l1);
while(li.hasPrevious())
{
String str = (String)li.previous();
if("haha".equals(str))
li.remove();
}
System.out.println(l1);
}
}
LinkedList实现类:
LinkedList是List接口的实现类,它的一些特有方法:
void addFirst(E e) 将指定元素插入此列表的开头。
void addLast(E e) 将指定元素添加到此列表的结尾。
Object getFirst() 返回此列表的第一个元素。
Object getLast() 返回此列表的最后一个元素。
Object removeFirst() 删除并返回此列表的第一个元素。
Object removeLast() 删除并返回此列表的最后一个元素。
如果该集合为空,使用removeFirst(),和removeLast()时,会抛出NoSuchElementException
在JDK1.6之后出现了替代方法:
boolean offerFirst(E e) 在此列表的开头插入指定的元素。
boolean offerLast(E e) 在此列表末尾插入指定的元素
Object peekFirst() 获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
Object peekLast() 获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。
Object pollFirst() 获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
Object pollLast() 获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。
案例演示:
package com.itheima.linkedlist;
import java.util.LinkedList;
/*
* 使用LinkedList模拟一个堆栈或者队列数据结构
* 堆栈:先进后出
* 队列:先进先出 First in First out FiFo
* */
public class DuiLie {
private LinkedList link;
public DuiLie(LinkedList link)
{
this.link = link;
}
public void myAdd(Object obj)
{
link.addFirst(obj);
}
/*
* 先进先出
* */
public Object firstInFirstOut()
{
return link.removeLast();
}
/*
* 先进后出
* */
public Object firstInLastOut()
{
return link.removeFirst();
}
public boolean isNull()
{
return link.isEmpty();
}
}
package com.itheima.linkedlist;
import java.util.LinkedList;
public class DuiLieTest {
public static void main(String[] args) {
DuiLie dl = new DuiLie(new LinkedList());
dl.myAdd("黑马程序训练营");
dl.myAdd("JavaEE+Androd");
dl.myAdd("JavaEE+物联云计算");
dl.myAdd("haha");
while(!dl.isNull()){
System.out.println(dl.firstInFirstOut());
}
}
}
ArrayList实现类:
案例说明:
package com.itheima;
public class Person {
private String name;
private int age;
public Person(){}
public Person(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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
throw new RuntimeException("该对象不是Person或Person的子类型");
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}
}
import java.util.ListIterator;
import com.itheima.Person;
/*
* 需求:将自定义对象作为元素,添加到集合中,并去除重复元素
* 比如:存Person对象,同姓名,同年龄视为同一个人
* */
public class ArrayListDemo2 {
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add(new Person("zhangsan", 20));
al.add(new Person("lisi", 22));
al.add(new Person("wangwu", 25));
al.add(new Person("zhangsan", 20));
al.add(new Person("lisi", 22));
al.add(new Person("wangwu", 25));
al = singleElement(al);
System.out.println(al);
}
public static ArrayList singleElement(ArrayList al)
{
//定义临时容器
ArrayList temAl = new ArrayList();
//遍历老集合
ListIterator li = al.listIterator();
while(li.hasNext())
{
Person p = (Person)li.next();
if(!temAl.contains(p))
{
temAl.add(p);
}
}
return temAl;
}
}
Person类必须重写了equals()方法,才能去除重复元素.
因为List集合判断元素是否相等的方法contains(Object obj)和删除方法remove(Object obj)底层调用的是equals().
Set集合:
Set集合与Collection集合中的方法基本上完全一样,它没有提供额外的方法。Set集合是无序的,不允许包含重复元素。
Set判读两个对象是否相等是根据equals()方法,只要equals()返回true,add()就返回false。
案例说明:
public class SetTest{
public static void main(String[] args)
{
Set s = new Set();
//添加一个字符串对象
s.add("haha");
//再次添加一个字符串对象
//因为两个字符串通过equals比较相等
//所以添加失败,返回false
boolean result = s.add(new String("haha"));
}
}
HashSet实现类:
HashSet按Hash算法来存储元素,具有良好的存取和查找性能
当自定义对象放入HashSet中时,需要重写hashCode()和equals()方法。HashSet中每个能存储元素的"槽位"通常称为"桶",
如果多个元素的hashCode值相同,但equals返回false,就会在一个"桶"里存放多个元素,导致性能下降。
案例说明:
/*
* 需求:向HashSet集合中存入自定义对象,姓名和年龄都相等则表示同一个人
* 为了看到添加元素的比较的执行过程,在hashCode()和equals()中增加输出语句
* */
import com.itheima.Person;
public class HashSetTest {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new Person("zhangsan", 20));
hs.add(new Person("lisi", 22));
hs.add(new Person("wangwu", 25));
hs.add(new Person("zhangsan", 20));
hs.add(new Person("lisi", 22));
hs.add(new Person("wangwu", 25));
Iterator it = hs.iterator();
while(it.hasNext())
{
Person p = (Person)it.next();
System.out.println(p);
}
}
}
package com.itheima;
public class Person {
private String name;
private int age;
public Person(){}
public Person(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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
/*
* 重写equals()方法
* */
@Override
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
throw new RuntimeException("该对象不是Person或Person的子类型");
Person p = (Person)obj;
System.out.println("equals*******" + this.name);
return this.name.equals(p.name) && this.age == p.age;
}
/*
* 重写hashCode()方法
* */
@Override
public int hashCode()
{
System.out.println("hashCode*******" + this.name);
return name.hashCode() + age;
}
}
上面程序的执行结果:
hashCode*******zhangsan
hashCode*******lisi
hashCode*******wangwu
hashCode*******zhangsan
equals*******zhangsan
hashCode*******lisi
equals*******lisi
hashCode*******wangwu
equals*******wangwu
Person [name=wangwu, age=25]
Person [name=zhangsan, age=20]
Person [name=lisi, age=22]
TreeSet实现类:
TreeSet是SortedSet接口的实现类,正如SortedSet的名字所暗示,TreeSet可以确保集合元素处于排序状态
案例说明:
package com.itheima.treeset;
import java.util.TreeSet;
public class TreeSetTest {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add("bbc");
ts.add("abs");
ts.add("cba");
ts.add("bbk");
System.out.println(ts);
}
}
编译运行结果:[abs, bbc, bbk, cba]。可以看出:在默认情况下是按照自然顺序排列。
自然排序:
当向TreeSet集合添加元素时,会调用元素的compareTo(Object obj)方法来比较元素之间的大小。
当向集合添加自定义对象时,则该对象必须实现Compareble接口,并重写compareTo(Object obj)方法,
否则程序将抛出ClassCastException异常。
TreeSet集合判断元素的唯一性的标准是:通过compareTo(Object obj)方法,返回0,视为元素已存在
案例体现:
/*
* 需求:向TreeSet集合添加自定义Person对象,按照年龄排序
* 注意:排序时,当主要条件相同时,一定要判断次要条件
* 为了看到比较的过程,在compareTo(Object obj)方法中增加了输出语句
* */
package com.itheima;
public class Person implements Comparable {
private String name;
private int age;
public Person(){}
public Person(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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
/*
* 重写equals()方法
* */
@Override
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
throw new RuntimeException("该对象不是Person或Person的子类型");
Person p = (Person)obj;
System.out.println("equals*******" + this.name);
return this.name.equals(p.name) && this.age == p.age;
}
/*
* 重写hashCode()方法
* */
@Override
public int hashCode()
{
System.out.println("hashCode*******" + this.name);
return name.hashCode() + age;
}
/*
* 重写compareTo(Object obj)方法,让本对象具有比较性
* */
@Override
public int compareTo(Object obj) {
if(!(obj instanceof Person))
throw new RuntimeException("该对象不是Person或Person的子类型");
Person p = (Person)obj;
System.out.println(this.name + "...." + p.name);
if(this.age > p.age)
return 1;
if(this.age == p.age)
{
return this.name.compareTo(p.name);
}
return -1;
}
}
package com.itheima.treeset;
import java.util.Iterator;
import java.util.TreeSet;
import com.itheima.Person;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Person("zhangsan", 20));
ts.add(new Person("lisi", 22));
ts.add(new Person("wangwu", 25));
ts.add(new Person("zhangsan", 20));
ts.add(new Person("lisi", 22));
ts.add(new Person("zhaoliu", 25));
Iterator i = ts.iterator();
while(i.hasNext())
{
Person p = (Person)i.next();
System.out.println(p);
}
}
}
程序运行结果:
zhangsan....zhangsan
lisi....zhangsan
wangwu....zhangsan
wangwu....lisi
zhangsan....lisi
zhangsan....zhangsan
lisi....lisi
zhaoliu....lisi
zhaoliu....wangwu
Person [name=zhangsan, age=20]
Person [name=lisi, age=22]
Person [name=wangwu, age=25]
Person [name=zhaoliu, age=25]
Java中实现Comparable接口,并重写了compareTo(Object obj)的常用类:
BigDecimal、BigInteger、Character、Boolean、String、Date
定制排序:
当元素自身不具备比较性,或者具备的比较性不是我们所需要的,这时就需要让容器自身具备比较性。
通过实现Comparator接口,并重写compare(Object obj1, Object ojb2)方法,在创建TreeSet集合时,
通过TreeSet集合的构造器,将比较器对象传递给TreeSet。
案例体现:
package com.itheima.treeset;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
import com.itheima.Person;
public class TreeSetDemo2 {
public static void main(String[] args) {
@SuppressWarnings("unchecked")
TreeSet ts = new TreeSet(new Comparator()
{
@Override
public int compare(Object o1, Object o2) {
if(!(o1 instanceof Person) || !(o2 instanceof Person))
throw new RuntimeException("该对象不是Person或Person的子对象");
Person p1 = (Person)o1;
Person p2 = (Person)o2;
int num = p1.getName().compareTo(p2.getName());
if(num == 0)
return new Integer(p1.getAge()).compareTo(new Integer(p2.getAge()));
return num;
}
});
ts.add(new Person("zhangsan", 20));
ts.add(new Person("lisi", 22));
ts.add(new Person("wangwu", 25));
ts.add(new Person("zhangsan", 20));
ts.add(new Person("lisi", 22));
ts.add(new Person("zhaoliu", 25));
Iterator i = ts.iterator();
while(i.hasNext())
{
Person p = (Person)i.next();
System.out.println(p);
}
}
}
运行结果:
Person [name=lisi, age=22]
Person [name=wangwu, age=25]
Person [name=zhangsan, age=20]
Person [name=zhaoliu, age=25]
通过运行结果和上面程序运行结果比较可以看出:当两种排序都存在时,以定制排序为准
Map集合:
Map用于保存键值对,通过键访问值。因此Map里的key不允许重复,把Map里的key放在一起,就组成了一个Set集合
Map里的value可以重复,把Map里的value放在一起,又类似于一个List。
Map接口中的常用方法:
Object put(Object key, Object value):添加一个key-value对,如果集合中已有一个与该key相等的key-value对,
则新的value会把已存在的替换掉,并返回被替换掉的value,否则返回null.
void putAll(Map m):将m集合中的key-value对复制到当前集合
void clear():删除Map集合中的所有键值对
Object remove(Object key):删除指定key所对应的key-value对,返回key所对应的value,如果key不存在,返回null
boolean containsKey(Object obj):查询Map中是否包含指定的key,如果包含返回true
boolean containsValue(Object obj):查询Map中是否包含一个或多个value,如果包含返回true
boolean isEmpty():查询集合是否为空,是,返回true
int size():返回该Map集合的键值对个数。
Object get(Object key):通过键获取值,如果不存在key,返回null
Set keySet():返回该Map集合所有key组成的Set集合
Collection values():返回Map集合所有value组成的Collection集合
Set entrySet():将Map集合的映射关系存入Set集合,每个映射关系都是Map.Entry(Entry是Map的内部接口)类型
Map中包含了一个内部类Entry,该类封装了key-value对,该类提供了三个方法,供我们访问key-value。
Object getKey():返回该Entry里包含的key值
Object getValue():返回该Entry里包含的value值
Object setValue(V value):设置该Entry里包含的value值,并返回新的值
方法测试:
package com.itheima.map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class MapTest {
public static void main(String[] args) {
Map<String, Integer> m = new HashMap<String, Integer>();
m.put("张三",24);
System.out.println("被覆盖之前,张三的值:" + m.put("张三",23));
m.put("李四", 21);
m.put("猪八", 27);
m.put("重九", 29);
System.out.println("张三对应的值是:" + m.get("张三"));
System.out.println("王五对应的值是:" + m.get("王五"));
System.out.println("集合中是否有王五这个键:" + m.containsKey("王五"));
System.out.println("集合中是否有23这个值:" + m.containsValue(23));
System.out.println("集合中的键值对个数:" + m.size());
System.out.println("被删除的田七的值是:" + m.remove("田七"));
System.out.println("被删除的张三的值是:" + m.remove("张三"));
//遍历集合方式一
//返回m集合所有的键的Set集合
Set<String> s = m.keySet();
Iterator<String> i = s.iterator();
while(i.hasNext())
{
String key = i.next();
//通过键获取值
int value = m.get(key);
System.out.println(key + "********" + value);
}
System.out.println("***********************************");
/*
* 遍历集合方式二:
* */
Set<Map.Entry<String, Integer>> set = m.entrySet();
Iterator<Map.Entry<String, Integer>> it = set.iterator();
while(it.hasNext())
{
Map.Entry<String, Integer> map = it.next();
String keykey = map.getKey();
int valuevalue = map.getValue();
System.out.println(keykey + "********" + valuevalue);
}
}
}
测试结果:
被覆盖之前,张三的值:24
张三对应的值是:23
王五对应的值是:null
集合中是否有王五这个键:false
集合中是否有23这个值:true
集合中的键值对个数:4
被删除的田七的值是:null
被删除的张三的值是:23
重九********29
猪八********27
李四********21
***********************************
重九********29
猪八********27
李四********21
案例说明二:
package com.itheima.map;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/*
* 需求:或取一个字符串中每个字母出现的次数,打印结果如:a 3 b 4
* 分析:通过打印结果发现,每个字母都有对应的次数,具有映射关系,可以选择Map集合
* 思路:1:将字符串拆分成一个数组
* 2:定义TreeMap集合
* 3:遍历字符数组,将每一个字母作为键去查Map集合,如果返回null,将该字母和1存入到Map集合中;
* 如果返回不是null,说明该字母在Map集合内已经存在,并有对应的次数,那么就获取值并进行自增,然后将字母和自增后的次数存入集合
* 4:遍历集合
* */
public class TreeMapDemo2 {
public static void main(String[] args) {
TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
String str = "bbbccccddddaaaffeeee";
char[] arr = str.toCharArray();
for(int i = 0; i < arr.length; i++)
{
Integer value = tm.get(arr[i]);
if(value == null){
tm.put(arr[i], 1);
}
else{
value++;
tm.put(arr[i], value);
}
}
Set<Map.Entry<Character, Integer>> set = tm.entrySet();
Iterator<Map.Entry<Character, Integer>> it = set.iterator();
while(it.hasNext())
{
Map.Entry<Character, Integer> map = it.next();
char key = map.getKey();
int value = map.getValue();
System.out.println(key + " " + value);
}
}
}
Collections工具类:
Collections是Java提供的操作Set、List、Map等集合的工具类。
排序操作方法:
static void sort(List list):根据元素自然顺序对指定的List集合按升序进行排序
static void sort(List list, Comparator c):根据指定Comparator产生的顺序对List集合进行排序
static void shuffle(List list):对List集合进行随机排序
static void reverse(List list):反转指定List集合中元素的顺序
static <T> Comparator<T> reverseOrder():返回一个比较器,它强行逆转实现了Comparable接口的对象collection的自然顺序。
static <T> Comparator<T> reverseOrder(Comparator<T> cmp) 返回一个比较器,它强行逆转指定比较器的顺序。
static void rotate(List list, int i, int j):将指定集合中的i索引的元素和j索引的元素进行置换
演示:
package com.itheima.collections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class CollectionsDemo1 {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("aaa");
al.add("kobe");
al.add("kobe");
al.add("paul");
al.add("hello");
al.add("bbs");
System.out.println("原集合顺序:" + al);
Collections.sort(al);
System.out.println("调用sort(List list)方法后:" + al);
/*按照字符串的长度排序*/
Collections.sort(al, new Comparator<String>()
{
public int compare(String str1, String str2)
{
int len = str1.length() - str2.length();
if(len == 0)
{
return str1.compareTo(str2);
}
return len;
}
});
System.out.println("实现Comparator接口后:" + al);
Collections.reverse(al);
System.out.println("反转后的顺序:" + al);
Collections.shuffle(al);
System.out.println("随机顺序:" + al);
}
}
运行后的结果:
原集合顺序:[aaa, kobe, kobe, paul, hello, bbs]
调用sort(List list)方法后:[aaa, bbs, hello, kobe, kobe, paul]
实现Comparator接口后:[aaa, bbs, kobe, kobe, paul, hello]
反转后的顺序:[hello, paul, kobe, kobe, bbs, aaa]
随机顺序:[bbs, kobe, kobe, paul, aaa, hello]
查找和替换方法:
static Object max(Collection c):根据元素的自然顺序,返回集合元素的最大值
static Object max(Collection c, Comparator com):根据Comparator指定顺序返回集合的最大元素
static Object min(Collection c):根据元素的自然顺序,返回集合元素的最小值
static Object min(Collection c, Comparator com):根据Comparator指定顺序返回集合的最小元素
static int binarySearch(List list, Object key):使用二分查找法,返回指定元素在集合中出现的索引,
前提是集合处于排序状态,如果找不到返回-插入-1。
static void fill(List list, Object obj):将集合中的每一元素替换成obj。
static boolean replaceAll(List list, Object oldVal, Object newVal):使用newVal替换集合中所有的oldVal。
演示说明:
package com.itheima.collections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class CollectionsDemo2 {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("kfc");
al.add("extends");
al.add("hallo");
al.add("implemen");
al.add("abstract");
al.add("implemen");
System.out.println("集合中元素的最大值" + Collections.max(al));
/**/
String max = Collections.max(al, new Comparator<String>()
{
public int compare(String str1, String str2)
{
int len = str1.length() - str2.length();
if(len == 0)
return str1.compareTo(str2);
return len;
}
});
System.out.println("按字符串长度排列的最大值是:" + max);
Collections.replaceAll( al, "implemen", "implements");
System.out.println("替换implemen后的集合:" + al);
Collections.fill(al, "haha");
System.out.println("用haha替换后的集合:" + al);
}
}
运行结果:
集合中元素的最大值kfc
按字符串长度排列的最大值是:implemen
替换implemen后的集合:[kfc, extends, hallo, implements, abstract, implements]
用haha替换后的集合:[haha, haha, haha, haha, haha, haha]
同步控制方法:
Collections类中提供了多个同步方法,该方法可以将指定集合包装成线程同步的集合,
从而解决线程并发访问集合的安全问题。
static <T> Collection<T> synchronizedCollection(Collection<T> c)
返回指定 collection 支持的同步(线程安全的)collection。
static <T> List<T> synchronizedList(List<T> list)
返回指定列表支持的同步(线程安全的)列表。
static <K,V> Map<K,V> synchronizedMap(Map<K,V> m)
返回由指定映射支持的同步(线程安全的)映射。
static <T> Set<T> synchronizedSet(Set<T> s)
返回指定 set 支持的同步(线程安全的)set。
static <K,V> SortedMap<K,V> synchronizedSortedMap(SortedMap<K,V> m)
返回指定有序映射支持的同步(线程安全的)有序映射。
static <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s)
返回指定有序 set 支持的同步(线程安全的)有序 set。
演示:
public class SynchronizedDemo{
public static void main(String[] args)
{
Collection c = Collections.synchronizedCollection(new ArrayList());
List l = Collections.synchronizedList(new ArrayList());
Set s Collections.synchronizedSet(new HashSet());
}
}
可变参数:
JDK1.5之后出先的新特性,其实就是数组参数的简写形式,不用手动建立数组对象,只要将要操作的元素作为参数即可
隐式将这些参数封装成数组即可。
注意:方法的可变参数使用时,可变参数一定要定义在参数列表的最后面
示例:
package com.itheima;
public class ArrDemo {
public static void main(String[] args)
{
show("haha",1,2,3,54,32);
}
public static void show(String str,int...arr)
{
for(int item : arr)
{
System.out.print(item + " ");
}
}
}