Java基础---集合


集合类

{
    "Collection 框架的顶层接口": [
        {
            "List 有序(存入和取出的顺序一致)元素都有索引(角标)允许重复元素": [
                "ArrayList 内部是数组数据结构 是不同步的 替代了Vector 查询的速度很快",
                "LinkedList 内部是链表数据结构 是不同步的 增删元素的速度很快",
                "Vector 内部是数组数据结构 是同步的 增删 查询都很慢"
            ]
        },
        {
            "Set 元素不能重复 无序": [
                {
                    "HashSet 内部数据结构是哈希表 是不同步的": "LinkedHashSet 保存了记录的插入顺序"
                },
                "TreeSet 可以对Set集合的元素进行排序 是不同步的"
            ]
        },
        {
            "Map 主要用于存储健值对 根据键得到值 因此不允许键重复(重复了覆盖了) 但允许值重复": [
                {
                    "HashMap 是一个最常用的Map,它根据键的HashCode 值存储数据 根据键可以直接获取它的值 具有很快的访问速度": "LinkedHashMap 保存了记录的插入顺序"
                },
                "TreeMap 实现SortMap接口 能够把它保存的记录根据键排序 默认是按键值的升序排序 也可以指定排序的比较器"
            ]
        },
        "Comparable 让元素自身具备比较功能 元素就需要实现该接口 覆盖compareTo方法",
        "Coparator 让集合自身具备比较功能 定义一个类实现Comparator接口 覆盖compare方法",
        "Collections 是集合框架的工具类 里面的方法都是静态的",
        "Arrays 集合框架的工具类 里面的方法都是静态的"
    ]
}

集合类的由来:对象用于封装特有的数据,对象多了需要存储;如果对象的个数不确定,就使用集合容器进行存储。

集合特点:
1. 用于存储对象的容器。
2. 集合的长度是可变的。
3. 集合中不可以存储基本数据类型值。
集合容器因为内部的数据结构不同,有多种具体容器。不断的向上抽取,就形成了集合框架。
P.S.
数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的;集合长度是可变的。
数组中可以存储基本数据类型,集合只能存储对象。

Collection接口

框架的顶层Collection接口:

Collection的常见方法:

1、添加:

boolean add(Object obj);

boolean addAll(Collection coll);

2、删除:

boolean remove(Object obj);

boolean removeAll(Collection coll);

void clear();

3、判断:

boolean contains(Object obj);

boolean containsAll(Collection coll);

boolean isEmpty();//判断集合中是否有元素。

4、获取:

int zize();

Iterator iterator();//取出元素的方式:迭代器。

该对象必须依赖于具体容器,因为每一个容器的数据结构都不同,所以该迭代器对象是在容器中进行内部实现的,也就是iterator方法在每个容器中的实现方式是不同的。
对于使用容器者而言,具体的实现不重要,只要通过容器获取到该实现的迭代器的对象即可,也就是
iterator方法。
Iterator接口就是对所有的Collection容器进行元素取出的公共接口。

5、其它:

boolean retainAll(Collection coll);//取交集

Object toArray();//将集合转成数组

示例1:(Collection添加删除判断)

import java.util.*;
public class CollectionDemo
{
	public static void main(String[] args)
	{
		Collection coll = new ArrayList();
		show(coll);
		System.out.println("--------------");
		Collection c1 = new ArrayList();
		Collection c2 = new ArrayList();
		show(c1,c2);
	}

	public static void show(Collection coll)
	{
		//1、添加元素,add
		coll.add("abc1");
		coll.add("abc2");
		coll.add("abc3");
		System.out.println("coll:"+coll);//coll:[abc1,abc2,abc3]

		//2、删除元素,remove
		coll.remove("abc2");//会改变集合的长度
		System.out.println("coll:"+coll);//coll:[abc1,abc3]

		//清空集合
		//coll.clear();
		//System.out.println("coll:"+coll);//coll:[]
	}

	public static void show(Collection c1,Collection c2)
	{
		//给c1添加元素
		c1.add("abc1");
		c1.add("abc2");
		c1.add("abc3");
		c1.add("abc4");

		//给c2添加元素
		c2.add("abc2");
		c2.add("abc6");
		c2.add("abc7");

		System.out.println("c1:"+c1);//c1:[abc1,abc2,abc3,abc4]
		System.out.println("c2:"+c2);//c2:[abc2,abc6,abc7]

		//演示addAll
		//将c2中的元素添加到c1中
		c1.addAll(c2);
		System.out.println("c1:"+c1);//c1:[abc1,abc2,abc3,abc4,abc2,abc6,abc7]

		//演示removeAll
		//从c1集合中删除c2集合相同的元素
		boolean b = c1.removeAll(c2);
		System.out.println("removeAll:"+b);//removeAll true

		//演示containsAll
		boolean b1 = c1.containsAll(c2);
		System.out.println("containsAll:"+b1);//removeAll false

		//演示retainAll
		//取交集,保留和指定的集合相同的元素
		boolean b2 = c1.retainAll(c2);
		System.out.println("c1、c2交集:"+c1);//c1、c2交集:[]

	}
}
示例2: (Collection获取)
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class IteratorDemo
{
	public static void main(String[] args)
	{
		Collection coll = new ArrayList();
		coll.add("abc1");
		coll.add("abc2");
		coll.add("abc3");
		coll.add("abc4");
		System.out.println(coll);
		//使用了Collection中的iterator()方法。调用集合中的迭代器方法,是为了获取集合中的迭代器对象。
		Iterator it1 = coll.iterator();
		while(it1.hasNext())
		{
			System.out.println(it1.next());
		}

		//for循环结束,Iterator变量内存释放,更高效
		for(Iterator it2 = coll.iterator();it2.hasNext();)
		{
			System.out.println(it2.next());
		}
	}
}

List、Set

Collection

      |--List:有序(存入和取出的顺序一致),元素都有索引(角标),允许重复元素。

      |--Set :元素不能重复,无序。

Collection-->List 有序(存入和取出的顺序一致),元素都有索引(角标),允许重复元素。

特有的常见方法。

有一个共性特点就是都可以操作角标。

1、添加
void add(index,element);
void addAll(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集合可以完成对元素的增删改查。

示例:(List add remove get subList)

import java.util.ArrayList;
import java.util.List;
public class ListDemo
{
	public static void main(String[] args)
	{
		List list = new ArrayList();
		show(list);
	}

	public static void show(List list)
	{
		//添加元素
		list.add("abc1");
		list.add("abc2");
		list.add("abc3");
		sop(list);//["abc1","abc2","abc3"]
		//插入元素
		list.add(1,"abc22");
		sop(list);//["abc1","abc22","abc2","abc3"]
		//删除元素
		list.remove(2);
		sop(list);//["abc1","abc22","abc3"]
		//修改元素
		list.set(1,"abc8");
		sop(list);//["abc1","abc8","abc3"]
		//获取元素
		sop(list.get(0));//"abc1"
		//获取子列表
		sop(list.subList(0,2));//["abc1","abc8"]

		sop(list);["abc1","abc8","abc3"]

	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
示例2: (List遍历元素)
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
public class ListDemo
{
	public static void main(String[] args)
	{
		List list = new ArrayList();
		show(list);
	}

	public static void show(List list)
	{
		list.add("abc1");
		list.add("abc2");
		list.add("abc3");

		Iterator it = list.iterator();
		while(it.hasNext())
		{
			sop("next:"+it.next());
		}

		//list特有的取元素的方法之一
		for(int x = 0;x<list.size();x++)
		{
			sop("get:"+list.get(x));
		}
	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

在迭代器过程中,不要使用集合操作元素,容易出现异常:java.util.ConcurrentModificationException。

示例3:(可以使用Iterator接口的子接口ListIterator来完成在迭代中对元素进行更多的操作。)

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListDemo
{
	public static void main(String[] args)
	{
		List list = new ArrayList();
		
		list.add("abc1");
		list.add("abc2");
		list.add("abc3");

		sop(list);

		ListIterator it = list.listIterator();//获取列表迭代对象
		//它可以实现在迭代过程中完成对元素的增删查改。
		//注意:只有list集合具备该迭代功能。
		while(it.hasNext())
		{
			Object obj = it.next();
			if(obj.equals("abc3"))
			{
				it.add("abc9");
			}
		}

		sop("hasNext:"+it.hasNext());//false
		sop("hasPrevious:"+it.hasPrevious());//true
		while(it.hasPrevious())
		{
			sop("previous:"+it.previous());
		}
		/*
		previous:abc9
		previous:abc3
		previous:abc2
		previous:abc1
		*/
		sop(list)//[abc1,abc2,abc3,abc9]

	}

	
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
Vector、ArrayList、LinkedList

List:

     |--Vector:内部是数组数据结构,是同步的。增删,查询都很慢。

     |--ArrayList:内部是数组数据结构,是不同步的,替代了Vector。查询的速度很快。

     |--LinkedList:内部是链表数据结构,是不同步的。增删元素的速度很快。

LinkedList方法:

addFirst();
addLast();
jdk1.6版本后新方法:
offerFirst();与addFirst方法没有区别。
offerLast();与addLast方法没有区别。
---------------------------------------------------------
getFirst();//获取但不移除,如果链表为空,抛出NoSuchElementException。
getLast();
jdk1.6版本后新方法:
peekFirst();//获取但不移除,如果链表为空,返回null。
peekLast();
--------------------------------------------------------
removeFirst();//获取并移除,如果链表为空,抛出NoSuchElementException。
removeLast();
jdk1.6版本后新方法:
pollFirst();//获取并移除,如果链表为空,返回null;
pollLast();

Collection-->List-->Vector 内部是数组数据结构,是同步的。增删,查询都很慢。

示例1:(Vector addElement 遍历 )

import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
public class VectorDemo
{
	public static void main(String[] args)
	{
		Vector v = new Vector();
		v.addElement("abc1");
		v.addElement("abc2");
		v.addElement("abc3");

		Enumeration en = v.elements();
		while(en.hasMoreElements())
		{
			sop("nextElement:"+en.nextElement());
		}
		/*
		nextElement:abc1
		nextElement:abc2
		nextElement:abc3
		*/

		Iterator it = v.iterator();
		while(it.hasNext())
		{
			sop("next:"+it.next());
		}
		/*
		next:abc1
		next:abc2
		next:abc3
		*/
	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

Collection-->List-->LinkedList  内部是链表数据结构,是不同步的。增删元素的速度很快。

示例2:(LinkedList addFirst getFirst removeFirst)

import java.util.Iterator;
import java.util.LinkedList;
public class LinkedListDemo
{
	public static void main(String[] args)
	{
		LinkedList link = new LinkedList();
		link.addFirst("abc1");
		link.addFirst("abc2");
		link.addFirst("abc3");
		link.addFirst("abc4");
		Iterator it = link.iterator();
		while(it.hasNext())
		{
			System.out.println("next:"+it.next());
		}
		/*
		next:abc4
		next:abc3
		next:abc2
		next:abc1
		*/

		System.out.println("getFirst:"+link.getFirst());//getFirst:abc4 获取第一个,但是不删除
		System.out.println("getLast:"+link.getLast());//getLast:abc1
		System.out.println(link);//[abc4,abc3,abc2,abc1]
		System.out.println("removeFirst:"+link.removeFirst());//removeFirst:abc4 获取第一个,但是删除
		System.out.println("removeLast:"+link.removeLast());//removeLast:abc1
		System.out.println(link);//[abc3,abc2]

		//删除所有元素的方法
		while(!link.isEmpty())
		{
			System.out.println(link.removeFirst());
		}
		System.out.println(link);//[]

	}
}
使用LinkedList来模拟一个堆栈或者队列数据结构。

堆栈:先进后出 First In Last Out FILO

队列:先进先出 First In First Out FIFO

示例3:(LinkedLis模拟队列)

import java.util.LinkedList;
/**
队列:先进先出 First In First Out FIFO
*/
class DuiLie
{
	private LinkedList link;

	public DuiLie()
	{
		link = new LinkedList();
	}

	//队列的添加元素的功能。
	public void myAdd(Object obj)
	{
		link.addFirst(obj);
	}
	public Object myGet()
	{
		return link.removeLast();
	}
	public boolean isNull()
	{
		return link.isEmpty();
	}
}

public class DuiLieTest
{
	public static void main(String[] args)
	{
		DuiLie dl = new DuiLie();
		dl.myAdd("abc1");
		dl.myAdd("abc2");
		dl.myAdd("abc3");
		dl.myAdd("abc4");

		while(!dl.isNull())
		{
			System.out.println(dl.myGet());
		}
		/*
		abc1
		abc2
		abc3
		abc4
		*/
	}
}

Collection-->List-->ArrayList 内部是数组数据结构,是不同步的,替代了Vector。查询的速度很快。

示例4:(ArrayList操作对象)

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

class Person
{
	private String name;
	private int age;
	public Person()
	{
	}

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

	public String getName()
	{
		return this.name;
	}

	public void setAge(int age)
	{
		this.age = age;
	}

	public int getAge()
	{
		return this.age;
	}

}

public class ArrayListTest
{
	public static void main(String[] args)
	{
		ArrayList al = new ArrayList();
		al.add(new Person("lisi1",21));
		al.add(new Person("lisi2",22));
		al.add(new Person("lisi3",23));
		al.add(new Person("lisi4",24));
		Iterator it = al.iterator();
		while(it.hasNext())
		{
			Person p = (Person)(it.next());
			System.out.println(p.getName()+":"+p.getAge());
		}
		/*
		lisi1:21
		lisi2:22
		lisi3:23
		lisi4:24
		*/
	}
}

Collection-->Set 元素不能重复,无序。

Set接口中的方法和Collection一致。

Set

    |--HashSet:内部数据结构是哈希表,是不同步的。

    |--TreeSet:可以对Set集合的元素进行排序,是不同步的。

示例1:(set add 遍历)

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class HashSetDemo
{
	public static void main(String[] args)
	{
		Set hs = new HashSet();

		hs.add("haha");
		hs.add("haha");
		hs.add("heihei");
		hs.add("hehe");
		hs.add("xixi");

		Iterator it = hs.iterator();
		while(it.hasNext())
		{
			System.out.println(it.next());
		}
		/*
		haha
		heihei
		hehe
		xixi
		*/
	}
}

Collection-->Set-->HashSet 内部数据结构是哈希表,是不同步的。

哈希表确定元素是否相同

1. 判断的是两个元素的哈希值是否相同。如果相同,再判断两个对象的内容是否相同。
2. 判断哈希值相同,其实判断的是对象的HashCode方法。判断内容相同,用的是equals方法。
P.S.
如果哈希值不同,不需要判断equals。
示例1: (往HashSet集合中存储Person对象。如果姓名和年龄相同,视为同一个人,视为相同元素。)
import java.util.HashSet;
import java.util.Iterator;
class Person
{
	private String name;
	private int age;
	public Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}

	public String getName()
	{
		return this.name;
	}
	public int getAge()
	{
		return this.age;
	}

	public int hashCode()
	{
		return name.hashCode()+age*39;
	}
	
	public boolean equals(Object obj)
	{
		if(this == obj)
			return true;//同一个对象放两次,直接返回true

		if(!(obj instanceof Person))
			throw new ClassCastException("类型错误");

		Person p = (Person)obj;
		return this.name.equals(p.name) && this.age == p.age;
	}

}

public class HashSetTest
{
	public static void main(String[] args)
	{
		HashSet hs = new HashSet();
		hs.add(new Person("lisi4",24));
		hs.add(new Person("lisi7",27));
		hs.add(new Person("lisi1",21));
		hs.add(new Person("lisi9",29));
		hs.add(new Person("lisi7",27));

		Iterator it = hs.iterator();
		while(it.hasNext())
		{
			Person p = (Person)it.next();
			System.out.println(p.getName()+"..."+p.getAge());
		}
		/*
		lisi7...27
		lisi1...21
		lisi9...29
		lisi4...24
		*/
	}
}
示例2: (无序变有序,使用LinkHashSet。)
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
public class LinkedHashSetDemo
{
	public static void main(String[] args)
	{
		HashSet hs = new LinkedHashSet();
		hs.add("haha");
		hs.add("hehe");
		hs.add("xixi");
		hs.add("heihei");		

		Iterator it = hs.iterator();
		while(it.hasNext())
		{
			System.out.println(it.next());
		}
		/*
		haha
		hehe
		xixi
		heihei
		*/
	}
}

Collection-->Set-->TreeSet 可以对Set集合的元素进行排序,是不同步的。

TreeSet 判断元素唯一性的方式:就是根据比较方法的返回结果是否是0,是0,就是相同元素,不存。

TreeSet对元素进行排序的方式一: 让元素自身具备比较功能,元素就需要实现Comparable接口,覆盖compareTo方法。

示例1:(TreeSet第一种排序方式:自然排序)

import java.util.Iterator;
import java.util.TreeSet;
class Person implements Comparable
{
	private String name;
	private int age;
	public Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	public String getName()
	{
		return this.name;
	}
	public int getAge()
	{
		return this.age;
	}

	public int hashCode()
	{
		return this.name.hashCode()+age*39;
	}
	public boolean equals(Object obj)
	{
		if(this == obj)
		{
			return true;
		}

		if(!(obj instanceof Person))
		{
			throw new ClassCastException("类型错误");
		}
		Person p = (Person)obj;
		return this.name.equals(p.name) && this.age == p.age;
	}

	public int compareTo(Object o)
	{
		Person p = (Person)o;
		//先按照年龄排序,以免年龄相同的人,没有存进去
		int temp = this.age-p.age;
		return temp == 0?this.name.compareTo(p.name):temp;
	}
}

public class TreeSetDemo
{
	public static void main(String[] args)
	{
		TreeSet ts = new TreeSet();

		//以Person对象年龄进行从小到大排序 年龄相同再按姓名排序
		ts.add( new Person("zhangsan" ,28));
		ts.add( new Person("zzzz" ,23));
		ts.add( new Person("wangwu" ,23));
		ts.add( new Person("lisi" ,21));
		ts.add( new Person("lisi" ,21));
		ts.add( new Person("zhouqi" ,29));
		ts.add( new Person("zhaoliu" ,25));

		Iterator it = ts.iterator();
		while(it.hasNext())
		{
			Person p = (Person)it.next();
			System.out.println(p.getName()+":"+p.getAge());
		}
		/*
		lisi:21
		wangwu:23
		zzzz:23
		zhaoliu:25
		zhangsan:28
		zhouqi:29
		*/

	}
}
如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然顺序。怎么办?
可以使用TreeSet集合第二种排序方式:
让集合自身具备比较功能,定义一个类实现Comparator接口,覆盖compare方法。

将该类对象作为参数传递给TreeSet集合的构造函数。

示例2:(TreeSet第二种排序方式:比较器)

import java.util.Iterator;
import java.util.TreeSet;
import java.util.Comparator;
/**
创建了一个根据Person类的name进行排序的比较器。
*/
class ComparatorByName implements Comparator
{
	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;
	}
}
class Person implements Comparable
{
	private String name;
	private int age;
	public Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	public String getName()
	{
		return this.name;
	}
	public int getAge()
	{
		return this.age;
	}

	public int hashCode()
	{
		return this.name.hashCode()+age*39;
	}
	public boolean equals(Object obj)
	{
		if(this == obj)
		{
			return true;
		}

		if(!(obj instanceof Person))
		{
			throw new ClassCastException("类型错误");
		}
		Person p = (Person)obj;
		return this.name.equals(p.name) && this.age == p.age;
	}

	public int compareTo(Object o)
	{
		Person p = (Person)o;
		//先按照年龄排序,以免年龄相同的人,没有存进去
		int temp = this.age-p.age;
		return temp == 0?this.name.compareTo(p.name):temp;
	}
}

public class TreeSetDemo
{
	public static void main(String[] args)
	{
		//如果自定义类实现了Comparable接口,并且TreeSet的构造函数中也传入了比较器,那么将以比较器的比较规则为准。
		TreeSet ts = new TreeSet(new ComparatorByName());
		//以Person对象年龄进行从小到大排序 年龄相同再按姓名排序
		ts.add( new Person("zhangsan" ,28));
		ts.add( new Person("zzzz" ,23));
		ts.add( new Person("wangwu" ,23));
		ts.add( new Person("lisi" ,21));
		ts.add( new Person("lisi" ,21));
		ts.add( new Person("zhouqi" ,29));
		ts.add( new Person("zhaoliu" ,25));

		Iterator it = ts.iterator();
		while(it.hasNext())
		{
			Person p = (Person)it.next();
			System.out.println(p.getName()+":"+p.getAge());
		}
		/*
		lisi:21
		wangwu:23
		zhaoliu:25
		zhangsan:28
		zhouqi:29
		zzzz:23
		*/

	}
}
P.S.

如果自定义类实现了Comparable接口,并且TreeSet的构造函数中也传入了比较器,那么将以比较器的比较规则为准。

TreeSet集合的底层是二叉树进行排序的。

示例3:(对字符长度进行排序)

import java.util.Iterator;
import java.util.TreeSet;
import java.util.Comparator;
/**
创建了一个根据Person类的name进行排序的比较器。
*/
class ComparatorByName implements Comparator
{
	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;
	}
}

class ComparatorByLen implements Comparator
{
	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;
	}
}


public class TreeSetDemo
{
	public static void main(String[] args)
	{
		TreeSet ts = new TreeSet(new ComparatorByLen());
		ts.add( "aaaa");
		ts.add( "zz");
		ts.add( "nbag");
		ts.add( "cba");
		ts.add( "abc");
		Iterator it = ts.iterator();
		while(it.hasNext())
		{
			System.out.println(it.next());
		}
		/*
		zz
		abc
		cba
		aaaa
		nbag
		*/

	}
}

Map、HashMap、TreeMap

Collection-->Map 用于存储元素对(称作“键”和“值”),其中每个键映射到一个值。

Map:一次添加一对元素,Collection一次添加一个元素。
Map也称为双列集合,Collection集合称为单列集合。
其实Map集合中存储的就是键值对。
map集合中必须保证键的唯一性。

常用方法:
1、添加
value put(key,value):返回前一个和key关联的值,如果没有返回null。
2、删除
void clear():清空map集合。
value remove(Object key):根据指定的key删除这个键值对。
3、判断
boolean containsKey(key);
boolean containsValue(value);
boolean isEmpty();
4、获取
value get(key):通过键获取值,如果没有该键返回null。
当然可以通过返回null,来判断是否包含指定键。

int size():获取键值对个数。

示例1(Map put remove containsKey)

import java.util.HashMap;
import java.util.Map;
public class  MapDemo
{
	public static void main(String[] args) 
	{
		Map<Integer,String> map = new HashMap<Integer,String>();
		method(map);
	}

	public static void method(Map<Integer,String> map)
	{
		//添加元素
		//以前与 key 关联的值,如果没有针对 key 的映射关系,则返回 null。有则返回以前对应的值
		//(如果该实现支持 null 值,则返回 null 也可能表示此映射以前将 null 与 key 关联)。 
		sop(map.put(8,"旺财"));//null 
		sop(map.put(8,"小强"));//旺财
		sop(map);//{8,小强}

		map.put(2,"张三");
		map.put(5,"赵七");
		sop(map);//{2=张三,5=赵七,8=小强}

		//删除
		sop("remove:"+map.remove(2));//张三
		//判断
		sop("containsKey:"+map.containsKey(5));//containsKey:true
		//获取
		sop("get:"+map.get(5));//get:赵七

	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
示例2: (Map遍历)

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Iterator;
import java.util.Collection;
public class  MapDemo
{
        public static void main(String[] args) 
        {
	         Map<Integer,String> map = new HashMap<Integer,String>();
	         method(map);
 	}


	public static void method(Map<Integer,String> map)
	{
		map.put(8,"旺财"); 
	        map.put(3,"小强");
		map.put(2,"王五");
		//获取Map集合元素并打印方式一:
 	        //取出map中的所有元素。
	        //原理,通过keySet方法获取map中所有的键所在的set集合,在通过set迭代器获取到每一个键。
		//再对每一个键通过map集合的get方法获取对应的值即可。
		Set<Integer> keySet = map.keySet();
		Iterator<Integer> it = keySet.iterator();
		while(it.hasNext())
		{
			Integer key = it.next();
			String value = map.get(key);
			sop(key+":"+value);
		}
		/*
		2:王五
		3:小强
		8:旺财
		*/


		//获取Map集合元素并打印方式二:
		Set<Map.Entry<Integer,String>> entrySet = map.entrySet();
		Iterator<Map.Entry<Integer,String>> it2 = entrySet.iterator();
		while(it2.hasNext())
		{
			Map.Entry<Integer,String> me = it2.next();
			Integer key = me.getKey();
			String Value = me.getValue();
			sop(key+":"+Value);
		}
		/*
		2:王五
		3:小强
		8:旺财
		*/
		//获取Map集合元素并打印方式三:
		Collection<String> values = map.values();
		Iterator<String> it3 = values.iterator();
		while(it3.hasNext())
		{
			sop(it3.next());
		}
		/*
		王五
		小强
		旺财
		*/


	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
Map常用的子类:
   |--Hashtable:内部结构是哈希表,是同步的。不允许null作为键,null作为值。
          |--Properties:用来存储键值对型的配置文件的信息,可以和IO技术相结合。
   |--HashMap:内部结构式哈希表,不是同步的。允许null作为键,null作为值。
   |--TreeMap:内部结构式二叉树,不是同步的。可以对Map结合中的键进行排序。

hashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。

Collection--> Map-->HashMap 是一个最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度
示例1:
(HashMap存储对象)

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


class Student
{
	private String name;
	private int age;
	public Student(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	public String getName()
	{
		return this.name;
	}
	public int getAge()
	{
		return this.age;
	}


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


	public boolean equals(Object obj)
	{
		if(this == obj)
		return true;
		if(obj == null)
		return false;
		if(!(obj instanceof Student))
		return false;
		Student other = (Student)obj;
		if(age!=other.age)
		return false;
		if(!name.equals(other.name))
		return false;
		return true;
	}
}
public class HashMapDemo
{
	public static void main(String[] args)
	{
		//将学生对象和学生归属地通过键值对存储到map集合中
		HashMap<Student,String> hm = new HashMap<Student,String>();
		hm.put( new Student("lisi" ,38),"北京");
		hm.put( new Student("zhaoliu" ,24),"上海");
		hm.put( new Student("xiaoqiang" ,31),"沈阳");
		hm.put( new Student("wangcai" ,28),"大连");
		hm.put( new Student("zhaoliu" ,24),"铁岭");
		Iterator<Student> it = hm.keySet().iterator();
		while(it.hasNext())
		{
			Student key = it.next();
			String value = hm.get(key);
			System.out.println(key.getName()+":"+key.getAge()+"---"+value);
		}


		//获取方式二
		Iterator<Map.Entry<Student,String>> it2 = hm.entrySet().iterator();
		while(it2.hasNext())
		{
			Map.Entry<Student,String> me = it2.next();
			Student key = me.getKey();
			String value = me.getValue();
			System.out.println(key.getName()+":"+key.getAge()+"---"+value);
		}
	}
}


P.S.
键有了判断依据,HashMap中的值就被覆盖。

使用LinkedHashMap则是跟原来存入的顺序是一致的

Map-->HashMap-->LinkedHashMap 保存了记录的插入顺序

示例2:(LinkedhashMap)

import java.util.*;
public class LinkedHashMapDemo
{
	public static void main(String[] args)
	{
		HashMap<Integer,String> hm = new LinkedHashMap<Integer,String>();
		hm.put(7,"zhouqi");
		hm.put(3,"zhangsan");
		hm.put(1,"qianyi");
		hm.put(5,"wangwu");
		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);
		}

	}
}

Collection-->Map-->TreeMap 实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器
示例1:
(“fdqavcbsacdfs”获取该字符串中,每一个字母出现的次数。要求打印结果是:a(2)b(1)...)

import java.util.*;

public class MapTest
{
	public static void main(String[] args)
	{
		String str = "sfsdfdsfsgagb";
		String s =getCharCount(str);
		System.out.println(s);
	}

	public static String getCharCount(String str)
	{
		//将字符串变为数组
		char[] chs = str.toCharArray();

		//定义map集合表
		Map<Character,Integer> map = new TreeMap<Character,Integer>();
		for(int i = 0;i<chs.length;i++)
		{
			if(!(chs[i]>='a' && chs[i]<='z' || chs[i]>='A' && chs[i]<='Z'))
				continue;
			//将数组中的字母作为键去查map表
			Integer value = map.get(chs[i]);
			int count = 0;
			//判断值是否为null
			if(value!=null)
				count=value;
			count++;
			map.put(chs[i],count);
		}
		return mapToString(map);
	}
	public static String mapToString(Map<Character,Integer> map)
	{
		StringBuilder sb = new StringBuilder();
		Iterator<Map.Entry<Character,Integer>> it = map.entrySet().iterator();
		while(it.hasNext())
		{
			Map.Entry<Character,Integer> me = it.next();
			Character key = me.getKey();
			Integer value = me.getValue();
			sb.append(key+"("+value+")");
		}

		/*Iterator<Character> it = map.keySet().iterator();

		while(it.hasNext())
		{
			Character key = it.next();
			Integer value = map.get(key);
			sb.append(key + "(" + value + ")" );
		 }*/

		return sb.toString();
	}

}

示例2: (Map在有映射关系时,可以优先考虑,在查表法中的应用较为多见。)

import java.util.*;
public class MapTest
{
	public static void main(String[] args)
	{
		String week = getWeek(1);
		System.out.println(week);
		System.out.println(getWeekByMap(week));
	}

	public static String getWeekByMap(String week)
	{
		Map<String,String> map = new HashMap<String,String>();
		map.put("星期一","Mon");
		map.put("星期二","Tue");
		map.put("星期三","Wes");
		map.put("星期日","Sun");
		map.put("星期天","Sun");
		return map.get(week);
	}

	public static String getWeek(int week)
	{
		if(week<1 || week>7)
			throw new RuntimeException("没有对应的星期");
		String[] weeks = {"","星期一","星期二"};
		return weeks[week];
	}
}


Collections工具类

Collections:是集合框架的工具类,里面的方法都是静态的。

示例1:(Collection.sort 及模拟Collection.sort 实现排序)

import java.util.*;
public class CollectionDemo
{
	public static void main(String[] args)
	{
		demo1();
	}

	public static void demo1()
	{
		List<String> list = new ArrayList<String>();
		list.add("abcde");
		list.add("cbs");
		list.add("aa");
		list.add("zzz");
		list.add("cbs");
		sop(list);
		//对list集合进行指定的顺序排序
		Collections.sort(list);
		sop(list);

		Collections.sort(list,new ComparatorByLength());
		sop(list);

		mySort(list,new ComparatorByLength());
		sop(list);
	}

	public static <T> void mySort(List<T> list,Comparator<? super T> comp)
	{
		for(int i = 0;i<list.size()-1;i++)
		{
			for(int j=i+1;j<list.size();j++)
			{
				if(comp.compare(list.get(i),list.get(j))>0)
				{
					//Collections.swap(list,i,j);
					T temp = list.get(i);
					list.set(i,list.get(j));
					list.set(j,temp);
				}
			}
		}
	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}

class ComparatorByLength implements Comparator<String>
{
	public int compare(String o1,String o2)
	{
		int temp = o1.length()-o2.length();
		return temp == 0?o1.compareTo(o2):temp;
	}
}

示例2:(Collections.binarySearch Collections.max)

import java.util.*;
public class CollectionDemo
{
	public static void main(String[] args)
	{
		demo2();
	}

	public static void demo2()
	{
		List<String> list = new ArrayList<String>();
		list.add("abcde");
		list.add("cba");
		list.add("aa");
		list.add("zzz");
		list.add("cba");
		list.add("nbaa");
		sop(list);
		Collections.sort(list);
		sop(list);
		int index = Collections.binarySearch(list,"aaa");//-2 //如果搜索键包含在列表中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。
		sop("index="+index);
		//获取最大值
		String max = Collections.max(list,new ComparatorByLength());
		sop(max);
	}

	

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
class ComparatorByLength implements Comparator<String>
{
	public int compare(String o1,String o2)
	{
		int temp = o1.length()-o2.length();
		return temp == 0?o1.compareTo(o2):temp;
	}
}

示例3: (Collections.reverseOrder反转)

import java.util.*;
public class CollectionDemo
{
	public static void main(String[] args)
	{
		demo3();
	}

	public static void demo3()
	{
		//[aa, abc, cba, zzz, hahahah]
		//TreeSet<String> ts = new TreeSet<String>(new ComparatorByLength()); 
		
		//[hahahah, zzz, cba, abc, aa]
		TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder(new ComparatorByLength()));
		ts.add("abc");
		ts.add("hahahah");
		ts.add("zzz");
		ts.add("aa");
		ts.add("cba");
		sop(ts);//[hahahah, zzz, cba, abc, aa]

	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
class ComparatorByLength implements Comparator<String>
{
	public int compare(String o1,String o2)
	{
		int temp = o1.length()-o2.length();
		return temp == 0?o1.compareTo(o2):temp;
	}
}

示例4: (Collections.replaceAll)

import java.util.*;
public class CollectionDemo
{
	public static void main(String[] args)
	{
		demo4();
	}

	public static void demo4()
	{
		List<String> list = new ArrayList<String>();
		list.add("abcde");
		list.add("cba");
		list.add("aa");

		sop(list);
		Collections.replaceAll(list,"cba","nba");
		sop(list);

	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
class ComparatorByLength implements Comparator<String>
{
	public int compare(String o1,String o2)
	{
		int temp = o1.length()-o2.length();
		return temp == 0?o1.compareTo(o2):temp;
	}
}

示例5: (Collection.shuffle)

import java.util.*;
public class CollectionDemo
{
	public static void main(String[] args)
	{
		demo5();
	}

	public static void demo5()
	{
		List<String> list = new ArrayList<String>();
		list.add("abcde");
		list.add("cba");
		list.add("aa");
		list.add("ccc");
		list.add("zzz");

		sop(list);
		Collections.shuffle(list);
		sop(list);

	}

	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}


示例6:(给非同步的集合加锁。)

import java.util.*;
public class TestDemo
{
	public static void main(String[] args)
	{
		List list = new ArrayList();//非同步的
		list = new MyCollections().synList(list);//同步的
	}

	
}
class MyCollections
{
	public List synList(List list)
	{
		return new MyList(list);
	}

	private class MyList extends ArrayList
	{
		private List list;
		private final Object lock = new Object();
		MyList(List list)
		{
			this.list = list;
		}
		public boolean add(Object obj)
		{
			synchronized(lock)
			{
				return list.add(obj);
			}
		}
		public boolean remove(Object obj)
		{
			synchronized(lock)
			{
				return list.remove(obj);
			}
		}
	}
}
Arrays工具类
Arrays:集合框架的工具类,里面的方法都是静态的。

示例1:(Arrays.toString)

import java.util.*;
public class TestDemo
{
	public static void main(String[] args)
	{
		int[] arr = {1,2,66,8,6,87};
		System.out.println(Arrays.toString(arr));
	}
}

重点:List asList(数组)将数组转成集合。
好处:可以使用集合的方法操作数组。

示例2:(Arrays.asList1)

import java.util.*;
public class TestDemo
{
	public static void main(String[] args)
	{
		String[] arr = {"sdf","ss","aa","ccc"};
		List<String> lis = Arrays.asList(arr);
		System.out.println(lis.contains("ss"));
	}
}

P.S.
数组的长度是固定的,所以对于结合的增删方法是不可以使用的,否则,会发生UnsupportedOperationException。

数组转集合,用asList方法。
如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。
如果数组中的元素是基本类型数值,那么会将该数组作为集合中的元素进行存储。

示例3:(Arrays.asList 2)

import java.util.*;
public class TestDemo
{
	public static void main(String[] args)
	{
		int[] arr1 = {31,56,11,12};
		List lis = Arrays.asList(arr1);
		System.out.println(lis);//[[I@2a139a55]
		List lis1 = Arrays.asList(arr1);
		System.out.println(lis1);//[[I@2a139a55]

		Integer[] arr2 = {31,56,11,12};
		List list2 = Arrays.asList(arr2);
		System.out.println(list2);//[31,56,11,12]
	}
}

集合转数组
使用的就是Collection接口中的toArray方法。
集合转成数组,可以对集合中的元素操作的方法进行限定,不允许对其进行增删。
toArray方法需要传入一个指定类型的数组。

长度该如何定义呢?
如果长度小于集合的size,那么该方法会创建一个同类型并和集合相同的size的数组。
如果长度大于集合的size,那么该方法就会使用指定的数组,存储集合中的元素,其他位置默认为null。
所以建议,最后长度就指定为,集合的size。

示例4:(集合转数组)

import java.util.*;
public class TestDemo
{
	public static void main(String[] args)
	{
		List<String> list = new ArrayList<String>();
		list.add("abc1");
		list.add("abc2");
		list.add("abc3");
		String[] arr = list.toArray(new String[list.size()]);
		System.out.println(Arrays.toString(arr));
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值