------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
类层次结构:
Collection(接口)
|--List(接口):1.有序的;2.可以存储重复值;
|--ArrayList(类):数组实现;
|--Set(接口):1.无序的;2.不能存储重复值;
/*
* Collection中的基本方法:
*
* 注意:如果大家在方法的形参或返回值类型中看到E字母,可以把它当做:Object
* boolean add(Object e):将参数e添加到集合
* boolean remove(Object o):将参数o从集合中移除
* void clear():清空集合
* boolean contains(Object o):基于equals()进行判断;
* boolean isEmpty():判断集合是否为空
* int size():集合中元素的数量;
*
*
* 学习:Collection(List和Set的顶层接口)
* 使用:子类:ArrayList
*/
public class Demo {
public static void main(String[] args) {
//1.定义集合对象
Collection col = new ArrayList();//多态:可存储重复元素
Collection col2 = new HashSet();//不能存储重复元素;
//2.向仓库中添加元素
System.out.println(col.add("孙悟空"));
System.out.println(col.add("猪八戒"));
System.out.println(col.add("沙师弟"));
System.out.println(col.add("唐僧"));
System.out.println(col.add("唐僧"));
System.out.println("---------------------------");
System.out.println(col2.add("孙悟空"));
System.out.println(col2.add("猪八戒"));
System.out.println(col2.add("孙悟空"));
System.out.println("集合元素:" + col);
//3.移除元素
System.out.println("删除元素:唐僧: " + col.remove("唐僧"));
System.out.println("删除元素:白骨精:" + col.remove("白骨精"));
System.out.println("集合元素:" + col);
//4.void clear()
// col.clear();
// System.out.println("清空集合后:" + col);
//5.boolean contains(Object o)
System.out.println("是否包含:白骨精:" + col.contains("白骨精"));
System.out.println("是否包含:孙悟空:" + col.contains("孙悟空"));
//6.boolean isEmpty()
// col.clear();
System.out.println("集合是否为空:" + col.isEmpty());
//7.int size():
System.out.println("集合中元素的数量:" + col.size());
//存储Student对象,使用数据,一旦定义长度,之后就不能改变;
//所以,如果我们使用"集合"存储,我们就不用关心长度的问题;
}
}
/*
* Collection中批量操作元素的方法:
*
* boolean addAll(Collection c):将参数集合,一次性全部添加到当前集合
* boolean removeAll(Collection c):移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作
* boolean containsAll(Collection c):如果此 collection 包含指定 collection 中的所有元素,则返回 true
* boolean retainAll(Collection c):移除此 collection 中未包含在指定 collection 中的所有元素。
*/
public class Demo {
public static void main(String[] args) {
Collection c1 = new ArrayList();
c1.add("孙悟空");
c1.add("猪八戒");
c1.add("唐三藏");
Collection c2 = new ArrayList();
c2.add("白骨精");
c2.add("蜘蛛精");
c2.add("狐狸精");
//将集合c2中的所有元素,一次性全部添加到c1中
/*c1.addAll(c2);
System.out.println("c1.size : " + c1.size());//6
System.out.println("c2.size : " + c2.size());//3
System.out.println("c1 : " + c1);
System.out.println("c2 : " + c2);
*/
/*c1.removeAll(c2);
System.out.println("c1 : " + c1);
System.out.println("c2 : " + c2);*/
// System.out.println(c1.containsAll(c2));
System.out.println(c1.retainAll(c2));
System.out.println("c1 : " + c1);
System.out.println("c2 : " + c2);
}
}
/*
* 对于Collection类型的集合,有两种基本的遍历方法:
*
* 1.Object[] toArray()方法:
* 2.迭代器:Iterator iterator();
*
* Iterator(接口):
* boolean hasNext(): 如果仍有元素可以迭代,则返回 true。
* Object next() :返回迭代的下一个元素。
*/
public class Demo {
public static void main(String[] args) {
Collection c1 = new ArrayList();
c1.add("孙悟空");
c1.add("猪八戒");
c1.add("唐三藏");
//遍历方式一:
Object[] objArray = c1.toArray();
for(int i = 0;i < objArray.length ; i++){
System.out.println(objArray[i]);
}
System.out.println("---------------------------");
//遍历方式二:迭代器
Iterator it = c1.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
interface Iterator{
boolean hasNext();
Object next();
void remove();
}
interface Collection{
Iterator iterator();
}
class ArrayList implements Collection{
public Iterator iterator() {
return new Itr();
}
private class Itr implements Iterator{
public boolean hasNext() {
return false;
}
public Object next() {
return null;
}
public void remove() {
}
}
}
/*
* Collection(接口):
* |--List(接口):1.可以存储重复的;2.有序的(取出时的顺序同存入时)
* 特有方法:
* void add(int index,E element):将element添加到index位置;原index位置上元素依次后移;
* E remove(int index):移除index位置上的元素
* E get(int index):获取index位置上的元素
* E set(int index,E element):将element替换原index位置上的元素;
*
* ListIterator listIterator():获取List的迭代器。ListIterator是Iterator的子接口;
* 跟Iterator的不同:
* 1.Iterator:单项的迭代器。只能向下遍历;
* 2.ListIterator:双向的迭代器,可以向上遍历;注意:在向上遍历前,一定要先向下遍历;
*
* |--Set(接口):1.不能存储重复元素;2.无序的;
*/
public class Demo {
public static void main(String[] args) {
//1.实例化一个集合
List list = new ArrayList();
list.add("张三");
list.add("李四");
list.add("王五");
Iterator it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//在"李四"之前,插入一个"赵七"
list.add(1,"赵七");
System.out.println("list :" + list);
//移除"赵七"
list.remove(1);
System.out.println("移除赵七后:" + list);
//获取王五
System.out.println("获取王五:" + list.get(2));
//将王五替换为赵七
list.set(2, "赵七");
System.out.println("将王五替换为赵七后:" + list);
//结合Collection的size()和List的get()方法,可以遍历List类型的集合:
for(int i = 0; i < list.size() ; i++){
System.out.println(list.get(i));
}
System.out.println("-----------------------");
//获取一个ListIterator
ListIterator listIt = list.listIterator();
System.out.println("先向下遍历:");
while(listIt.hasNext()){
System.out.println(listIt.next());
}
System.out.println("向上遍历:");
while(listIt.hasPrevious()){
System.out.println(listIt.previous());
}
System.out.println("=====================");
}
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/*
* 并发修改异常:
*
* 1.Iterator:remove()方法不会触发并发修改异常;
* 2.ListIterator:remove()方法不会触发并发修改异常;
* set()方法不会触发并发修改异常;
* add()方法不会触发并发修改异常;
* 3.当使用迭代器遍历元素时,通过List的对象去修改元素内容时,会引发并发修改异常:ConcurrentModificationException
* 解决:
* 使用迭代器遍历,如果要修改集合,就要通过迭代器去修改。不要通过List对象修改;
*/
public class Demo {
public static void main(String[] args) {
List list = new ArrayList();
list.add("张三");
list.add("李四");
list.add("王五");
ListIterator listIt = list.listIterator();
while(listIt.hasNext()){
String str = (String)listIt.next();
System.out.println(str);
if(str.equals("李四")){
// listIt.remove();//OK的
// listIt.set("赵七");//OK的
// listIt.add("赵七");//OK的
list.add("赵七");//并发修改异常:通过List对象去修改的;
}
}
System.out.println("----------------------");
Iterator it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import cn.itcast.domain.Student;
public class ArrayListTest {
/**
* @param args
*/
public static void main(String[] args) {
List list = new ArrayList();
// list.add("abc1");
// list.add("abc2");
// list.add("abc1");
// list.add("abc2");
// list.add("abc1");
// list.add("abc2");
list.add(new Student("lisi1",21));
list.add(new Student("lisi2",22));
list.add(new Student("lisi1",21));
list.add(new Student("lisi2",22));
list.add(new Student("lisi1",21));
getSingleElement(list);//去除重复元素。
System.out.println(list);
}
/*
* 案例:去除List集合中的重复元素。
*
* 思路:
* 1,先创建一个临时容器。用于存储唯一性的元素。
* 2,遍历原容器,将遍历到的元素到临时容器中去判断,是否存在。
* 3,如果存在,不存储到临时容器,如果不存在,存储到临时容器中。
* 4,遍历结束后,临时容器中存储的就是唯一性的元素。
* 5,如果需要将这些唯一性的元素保留到原容器中,只要将原容器清空,将临时容器中的元素添加到原容器中即可。
*
*/
public static void getSingleElement(List list){
//1,创建一个临时容器。
List temp = new ArrayList();
//2,遍历原容器。
for (Iterator it = list.iterator(); it.hasNext();) {
Object obj = it.next();
//对遍历到的每一个元素都到临时容器中去判断是否包含。
if(!temp.contains(obj)){//如果不存在,
temp.add(obj);//添加到临时容器。
}
}
//唯一性的元素已经被记录到临时容器中。
//清空原容器中的元素。
list.clear();
//把临时容器中的元素添加到原容器中。
list.addAll(temp);
}
}
import java.util.LinkedList;
public class LinkedListDemo {
/**
* @param args
*/
public static void main(String[] args) {
/*
* LinkedList做个了解。
* 特有:围绕头和尾展开定义的。First Last。
* addFirst();
* addLast();
*
* getFirst();:获取头部元素。
* getLast();
*
* removeFirst();获取头部元素,并删除头部元素。
* removeLast();
*/
LinkedList link = new LinkedList();
link.addFirst("abc1");
link.addFirst("abc2");
link.addFirst("abc3");
// System.out.println(link.getFirst());
// System.out.println(link.getFirst());
// System.out.println(link.removeFirst());
// System.out.println(link.removeFirst());
// System.out.println(link.removeFirst());
// System.out.println(link.removeFirst());
while(!link.isEmpty()){
System.out.println(link.removeLast());
}
}
}
import java.util.LinkedList;
public class LinkedListTest {
/**
* @param args
*/
public static void main(String[] args) {
/*
* 面试题:用LinkedList模拟一个堆栈或者队列数据结构。
* 创建一个堆栈或者队列数据结构对象,该对象中使用LinkedList来完成的。
*
* 自定义堆栈结构。作业。
*/
//创建一个队列对象。
Queue queue = new Queue();
//往队列中添加元素。
queue.myAdd("itcast1");
queue.myAdd("itcast2");
queue.myAdd("itcast3");
queue.myAdd("itcast4");
while(!queue.isNull()){
System.out.println(queue.myGet());
}
}
}
/**
* 定义一个队列数据结构。Queue
*/
class Queue{
//封装了一个链表数据结构。
private LinkedList link;
/*
* 队列初始化时,对链表对象初始化。
*/
Queue(){
link = new LinkedList();
}
/**
* 队列的添加元素功能。
*/
public void myAdd(Object obj){
//内部使用的就是链表的方法。
link.addFirst(obj);
}
/**
* 队列的获取方法。
*/
public Object myGet(){
return link.removeLast();
}
/**
* 判断队列中元素是否空,没有元素就为true。
*/
public boolean isNull(){
return link.isEmpty();
}
}
Set:不包含重复元素的集合,不保证顺序。而且方法和Collection一致。Set集合取出元素的方式只有一种:迭代器。
|--HashSet:哈希表结构,不同步,保证元素唯一性的方式依赖于:hashCode(),equals()方法。查询速度快。
|--TreeSet:可以对Set集合中的元素进行排序。使用的是二叉树结构。如何保证元素唯一性的呢?
使用的对象比较方法的结果是否为0,是0,视为相同元素不存。
元素的排序比较有两种方式:
1,元素自身具备自然排序,其实就是实现了Comparable接口重写了compareTo方法。
如果元素自身不具备自然排序,或者具备的自然排序不是所需要的,这时只能用第二种方式。
2,比较器排序,其实就是在创建TreeSet集合时,在构造函数中指定具体的比较方式。
需要定义一个类实现Comparator接口,重写compare方法。
到此为止:再往集合中存储对象时,通常该对象都需要覆盖hashCode,equals,
同时实现Comparale接口,建立对象的自然排序。通常还有一个方法也会复写toString();
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import cn.itcast.domain.Student;
public class SetDemo {
/**
* @param args
*/
public static void main(String[] args) {
Set set = new HashSet();
/*
// 去除了字符串中的重复元素。
set.add("nba");
set.add("java");
set.add("haha");
set.add("itcast");
set.add("haha");
set.add("java");
set.add("java");
set.add("java");
set.add("itcast");*/
/*
*
* 为什么学生对象没有保证唯一性呢?
* 通过对哈希表的分析。
* 存储元素时,先调用了元素对象的hashCode()方法,而每个学生对象都是新建立的对象,
* 所以hashCode值都不相同,也就不需要判断equals了。
* 想要按照需求同姓名同年龄来保证学生对象的唯一性咋办?
* 不能使用Object中hashCode方法,需要重新定义hashCode的算法内容。
* 简单说:重写hashCode方法。
*/
set.add(new Student("lisi1",21));
set.add(new Student("lisi2",22));
set.add(new Student("lisi1",21));
set.add(new Student("lisi2",22));
set.add(new Student("lisi1",21));
"abc1".hashCode();
for (Iterator it = set.iterator(); it.hasNext();) {
System.out.println(it.next());
}
}
}
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import cn.itcast.api.d.comparator.ComparatorByLength;
public class HashSetTest {
/**
* @param args
*/
public static void main(String[] args) {
Set set = new HashSet();
set.add("abcde");
set.add("haha");
set.add("z");
set.add("java");
// Object max = Collections.max(set);
// System.out.println("max="+max);
Object obj1 = getMax(set);
System.out.println(obj1);
// Object obj2 = getMax(set,new ComparatorByLength());
// System.out.println(obj2);
}
/**
* 获取Set集合的最大值,通过自然排序。
* @param set
* @return
*/
public static Object getMax(Set set) {
/*
* 最值思路: 1,需要比较,并记录每次比较后较大的值。不断的重复这个动作(循环)
*/
// 1,定义变量,记录较大的值,初始化为元素中的任意一个。
// 取出set集合中一个元素,通过迭代器。
// 先获取迭代器。
Iterator it = set.iterator();
// 获取其中一个元素。
Object max = it.next();
// 2,遍历集合,获取集合的每一个元素,
while (it.hasNext()) {
Object o = it.next();
Comparable temp = (Comparable) o;
// 3,在遍历中,和变量中记录的元素进行比较。让变量记录住比较后较大值。
if (temp.compareTo(max) > 0) {
max = temp;
}
}
// 4,返回最大值。
return max;
}
/**
* 获取Set集合最大值,通过给定的比较器。
* @param set
* @param comp
* @return
*/
public static Object getMax(Set set, Comparator comp) {
if (comp == null) {
throw new NullPointerException();
}
/*
* 最值思路: 1,需要比较,并记录每次比较后较大的值。不断的重复这个动作(循环)
*/
// 1,定义变量,记录较大的值,初始化为元素中的任意一个。
// 取出set集合中一个元素,通过迭代器。
// 先获取迭代器。
Iterator it = set.iterator();
// 获取其中一个元素。
Object max = it.next();
// 2,遍历集合,获取集合的每一个元素,
while (it.hasNext()) {
Object o = it.next();
// 3,在遍历中,和变量中记录的元素进行比较。让变量记录住比较后较大值。
if (comp.compare(o, max) > 0) {
max = o;
}
}
// 4,返回最大值。
return max;
}
}
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
public class LinkedHashSetDemo {
/**
* @param args
*/
public static void main(String[] args) {
/*
* 提高唯一性元素的查询效率,还想有序,可使用HashSet的子类LinkedHashSet.
*/
Set set = new LinkedHashSet();
set.add("abcd");
set.add("hahahah");
set.add("java");
set.add("itcast");
for (Iterator it = set.iterator(); it.hasNext();) {
System.out.println(it.next());
}
}
}
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import cn.itcast.domain.Student;
public class TreeSetDemo {
/**
* @param args
*/
public static void main(String[] args) {
//演示TreeSet,
Set set = new TreeSet();
/*
set.add("nba");
set.add("abc");
set.add("java");
set.add("aaa");
*/
/*
* TreeSet的add方法内部最终实现:
* 需要将元素转成Comparable类型,为什么?因为这个类型具备排序的能力。
* 这个类型中有一个专门为排序提供了一个compareTo方法。
* 如果要让学生具备比较排序的功能,需要让学生扩展功能,实现Comparable接口。
*/
set.add(new Student("lisi6",21));
set.add(new Student("lisi8",22));
set.add(new Student("lisi5",25));
set.add(new Student("lisi3",23));
set.add(new Student("lisi7",20));
for (Iterator it = set.iterator(); it.hasNext();) {
System.out.println(it.next());
}
}
}
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
import cn.itcast.api.d.comparator.ComparatorByName;
import cn.itcast.domain.Student;
public class TreeSetDemo2 {
/**
* @param args
*/
public static void main(String[] args) {
//在创建TreeSet集合对象时明确比较器。
Set set = new TreeSet(new ComparatorByName());
/*
* 想要按照学生的姓名排序,说明学生中的自然排序不是所需要的。
* 这时只能使用比较器。ComparatorByName。
*/
set.add(new Student("lisi6",21));
set.add(new Student("lisi8",22));
set.add(new Student("lisi5",25));
set.add(new Student("lisi3",23));
set.add(new Student("lisi7",20));
for (Iterator it = set.iterator(); it.hasNext();) {
System.out.println(it.next());
}
}
}
import java.util.Comparator;
import java.util.TreeMap;
import cn.itcast.domain.Student;
public class ComparatorByName extends Object implements Comparator {
@Override
public int compare(Object o1, Object o2) {
//1,因为要比较的是学生对象的姓名。所以向下转型成Student对象。
Student s1 = (Student)o1;
Student s2 = (Student)o2;
//先比较姓名。
int temp = s1.getName().compareTo(s2.getName());
//如果姓名相同,再比较年龄。
return temp==0? s1.getAge()-s2.getAge():temp;
}
}
集合分体系。List Set
子类对象的后缀名是所属体系,前缀名是数据结构名称。
List:新出的子类都是以List结尾的,通常都是非同步的。
|--ArrayList:看到array,就知道数组,查询速度快。
|--LinkedList:看到link,就知道链表,增删速度快。
Set:
|--HashSet:看到hash,就知道哈希表,查询速度更快,并想到元素唯一,通过hashCode(),equals方法保证唯一性。
|--TreeSet:看到tree,就知道二叉树,可以排序,排序想到Comparable-compareToComparator--compare方法。
1,因为集合可以存储的对象类型是任意的,在取出进行向下转型时,容易发生ClassCastException。
所以JDK1.5以后就有了解决这个问题的技术:泛型。
2,泛型的原理:其实就是在操作的元素类型不确定时,通过传递参数的形式来明确类型。
3,泛型的体现就是 <参数类型变量>用于接收具体的实际元素类型。
4,泛型技术在集合框架中应用非常广泛,只要记住:在使用类或者接口时,如果接口上有明确<>泛型。在使用时,就传递所需的数据类型即可。不传递会出现警告类型不安全提示。
5,了解:泛型技术是用在编译器部分的技术,一旦类型检查正确,
生成的class文件中就没有泛型标记了:这是的泛型的擦除。
6,泛型的好处:
6.1 将运行时期的ClassCastException异常转移到编译时期通过编译失败体现。
6.2 避免了强制转换的麻烦。
7,其实泛型的使用就是往定义了泛型的类或者接口的<>中传递类型参数。
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class GenericDemo {
/**
* @param args
*/
public static void main(String[] args) {
/*
* 为了让集合使用更安全,
* 问题:什么类型的元素都可以存储。导致取出时,如果出现强转就会引发运行时 ClassCastException。
* 能不能在创建集合时,就明确容器中的元素的类型,如同数组一样。
* 目的是为了更安全。
* JDK1.5以后,出现了解决方案,使用容器时,必须明确容器中元素的类型。
* 这种机制:称之为 :泛型。
* 体现 <数据类型>,不是很难理解,<>也是括号,往括号里面写东西其实就是在传递参数。
* 泛型:
* 1,安全机制。
* 2,将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
* 3,泛型技术,是给编译器使用的技术。
* 4,避免了强转的麻烦。
*/
//int[] arr = new int[];
//创建集合时,直接在集合上明确要存储的元素的类型。
List list = new ArrayList();
list.add("abc");
list.add("zzzz");
// list.add(6);//只要不是指定的类型对象,编译器检查会 报错。这样将运行时的问题转移到编译时期。
for (Iterator it = list.iterator(); it.hasNext();) {
// Object object = (Object) it.next();
// System.out.println(object.toString());
//想要打印字符串的长度。
String str = it.next();
System.out.println(str.length());
}
}
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import cn.itcast.domain.Person;
import cn.itcast.domain.Student;
import cn.itcast.domain.Worker;
public class GenericDemo6 {
/**
* @param args
*/
public static void main(String[] args) {
Set list = new HashSet();
list.add(new Student("lisi1",21));
list.add(new Student("lisi2",22));
list.add(new Student("lisi3",23));
printList(list);
List list2 = new ArrayList();
list2.add(new Worker("lisi11",21));
list2.add(new Worker("lisi22",22));
list2.add(new Worker("lisi33",23));
printList(list2);
}
/*
* 打印集合中的元素。
* 当使用泛型类或者接口时,传递的具体的类型不确定,可以通过通配符(?)表示。
* 如果想要对被打印的集合中的元素类型进行限制,只在指定的一些类型,进行打印。
* 使用泛型的限定。
*
* 只需要打印学生和工人的集合。找到学生和工人的共性类型Person。
* ? extends Person : 接收Person类型或者Person的子类型。
*
* 总结:
* ? super E:接收E类型或者E的父类型。下限。
* ? extends E:接收E类型或者E的子类型。上限。
*/
private static void printList(Collection extends Person> list2) {
for (Iterator extends Person> it = list2.iterator(); it.hasNext();) {
Person p = it.next();
System.out.println(p.getName());
}
}
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import cn.itcast.api.c.comparator.ComparatorByLength;
public class CollectionsDemo {
/**
* @param args
*/
public static void main(String[] args) {
/*
* Collections: 集合框架中的用于操作集合对象 工具类。
* 都是静态的工具方法。
* 1,获取Collection最值。
* 2,对List集合排序,也可以二分查找。
* 3,对排序逆序。
* 4,可以将非同步的集合转成同步的集合。
* Xxx synchronizedXxx(Xxx) List synchronizedList(List)
*/
System.out.println("---------获取最值---------------");
Collection c = new ArrayList();
c.add("haha");
c.add("zz");
c.add("xixii");
c.add("abc");
String max = Collections.max(c,new ComparatorByLength());
System.out.println("max="+max);
System.out.println("-----------排序-------------");
List list = new ArrayList();
list.add("hahaha");
list.add("abc");
list.add("xiix");
list.add("z");
list.add("java");
Collections.sort(list,Collections.reverseOrder());
System.out.println(list);
System.out.println("------------------------");
System.out.println("------------------------");
}
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class ArraysDemo {
/**
* @param args
*/
public static void main(String[] args) {
/*
* Arrays:用于操作数组的工具类。
* 类中定义的都是静态工具方法
* 1,对数组排序。
* 2,二分查找。
* 3,数组复制。
* 4,对两个数组进行元素的比较,判断两个数组是否相同。
* 5,将数组转成字符串。
*/
int[] arr = {34,21,67};
System.out.println(Arrays.toString(arr));
//将arr转成list集合。?如果数组中存储的是基本数据类型,那么转成集合,数组对象会作为集合中的元素存在。
//数组中元素时引用数据类型时,转成,数组元素会作为集合元素存在。
List list1 = Arrays.asList(arr);
System.out.println(list1);
String[] strs = {"hah","hehe","xixi"};
boolean b = contains(strs,"hehe");
System.out.println(b);
//将数组转成list集合。asList
/*
* 数组转成集合:就为了使用集合的方法操作数组中的元素。
* 但是不要使用增删等改变长度的方法。add remove 发生UnsupportedOperationException
*/
List list = Arrays.asList(strs);
System.out.println(list.contains("hehe"));
System.out.println(list.get(2));
System.out.println(list.indexOf("hehe"));
// list.add("java");//UnsupportedOperationException 数组长度的固定的,转成List集合长度也是固定的。
//-------------------集合转成数组---------------------
/*
* 为什么集合转成数组呢?
* 为了限制对元素的增删操作。
*/
Collection c = new ArrayList();
c.add("haha1");
c.add("haha2");
c.add("haha3");
c.add("haha4");
/*
* 如果传递的数组的长度小于集合的长度,会创建一个同类型的数组长度为集合的长度。
* 如果传递的数组的长度大于了集合的长度,就会使用这个数组,没有存储元素的位置为null。
* 长度最好直接定义为和集合长度一致。
*/
String[] str_arr = c.toArray(new String[c.size()]);
System.out.println(Arrays.toString(str_arr));
}
public static boolean contains(String[] strs,String key) {
for (int i = 0; i < strs.length; i++) {
if(strs[i].equals(key)){
return true;
}
}
return false;
}
}
1,为了解决集合的更多需求。集合框架提供了Collections和Arrays两个工具类,方法都是静态的。
2,Collections是用于操作集合的工具类。
常见方法:对List集合排序,二分查找,对Collection集合进行最值获取。
对排序进行逆序,将非同步的集合转成同步的集合。
3,Arrays对数组操作的工具类:
常见方法:对数组排序,二分查找,数组复制,将数组转成字符串等。
4,数组集合互转。
4.1将数组转成集合 Arrays.asList方法。
目的:使用集合的方法操作数组元素。
注意:不要使用集合的增删方法。因为数组转成List集合后长度是固定的。
转成集合的数组中存储的元素最好是对象,如果是基本数据类型,会将这个数组作为元素存储到集合中。
4.2集合转成数组。
Collection接口中的toArray方法。
目的:限定对元素的增删,长度的改变。
Map
|--Hashtable:数据结构:哈希表。是同步的,不允许null作为键和值。被hashMap替代。
|--Properties:属性集,键和值都是字符串,而且可以结合流进行键值的操作。等到了IO流,你会更清楚。
|--HashMap:数据结构:哈希表。不是同步的,允许null作为键和值。
|--LinkedHashMap:基于链表+哈希表。可以保证map集合有序(存入和取出的顺序一致)。
|--TreeMap:数据结构:二叉树。不是同步的。可以对map集合中的键进行排序。
什么时候使用map集合呢?
分析问题时出现对应关系,毫不犹豫的想到map集合。
如果对应关系中出现了有序的数字,想到数组。
注意:如果对应关系个数不确定,还是以map为主。
Map集合特点;
1,内部存储的都是键key值value对。
2,必须要保证的键的唯一性。
Map常见功能。
1,存储。v put(k,v);
2,获取。v get(k);
3,移除。v remove(k);
4,Set
5,Set
6,Collection
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class MapDemo2 {
/**
* @param args
*/
public static void main(String[] args) {
Map map = new HashMap();
map.put("星期一", "Monday");
map.put("星期日", "Sunday");
System.out.println("------------keySet方法的获取---------------");
// System.out.println(map.get("星期一"));
//怎么获取到所有的键呢?既然是所有的键,应该是一个集合,而且是一个单列集合。
//list还是set呢?应该是set,因为map集合中键需要保证唯一性。
//找到一个方法 Set keySet();获取map集合中的键的set集合。
Set keySet = map.keySet();
for(Iterator it= keySet.iterator(); it.hasNext() ; ){
String key = it.next();
String value = map.get(key);//通过键获取对应的值。
System.out.println(key+"::"+value);
}
//使用foreach循环,进行遍历。
for(String key : keySet){
System.out.println(key+":::::"+map.get(key));
}
System.out.println("-----------entrySet方法获取----------------");
/*
* Set entrySet():将map集合中映射关系存储到了Set集合中.
* 映射关系:其实就是指键和值的对应关系。其实就是夫妻的结婚证。
* 映射关系是什么类型的呢? Map.Entry
*/
Set> entrySet = map.entrySet();
Iterator> it = entrySet.iterator();
//遍历Set中的映射关系对象。
while(it.hasNext()){
Map.Entry me = it.next();//取到了映射关系对象。
//获取键。
String key = me.getKey();
//获取值。
String value = me.getValue();
System.out.println(key+"-----"+value);
}
/*
* 总结:map集合没有迭代器,取出元素的方式:将map集合转成单列结合,在使用单列集合的迭代器就可以了。
* map集合也不能直接被foreach循环遍历。
*/
for(Map.Entry me : map.entrySet()){
String key = me.getKey();
//获取值。
String value = me.getValue();
System.out.println(key+"--------"+value);
}
System.out.println("-----------获取所有值的方法 values()----------------");
/*
* 获取所有的值,因为值不需要保证唯一性。所以返回类型时Collection。
* 姓名--归属地。对应关系,获取所有的归属地。values();
*/
//所有的英文星期。
Collection values = map.values();
for(String value : values){
System.out.println("value:"+value);
}
}
}
import java.util.HashMap;
import java.util.Map;
import cn.itcast.domain.Student;
public class HashMapTest {
/**
* @param args
*/
public static void main(String[] args) {
/*
* 练习一:
* 学生对象(姓名,年龄)都有自己的归属地,既然有对应关系。
* 将学生对象和归属地存储到map集合中。
* 注意:同姓名同年龄视为重复的键。
*/
//1,创建hashmap集合对象。
Map map = new HashMap();
//2,添加元素。
map.put(new Student("lisi",28), "上海");
map.put(new Student("wangwu",22), "北京");
map.put(new Student("zhaoliu",24), "成都");
map.put(new Student("zhouqi",25), "广州");
map.put(new Student("wangwu",22), "南京");
//3,取出元素。keySet entrySet
// Set keySet = map.keySet();
// for(Student key : keySet){}
for(Student key : map.keySet()){
String value = map.get(key);
System.out.println(key.toString()+"....."+value);
}
}
}
import java.util.Map;
import java.util.TreeMap;
importcn.itcast.api.c.comparator.ComparatorByName;
import cn.itcast.domain.Student;
public class TreeMapTest {
/**
* @param args
*/
publicstatic void main(String[] args) {
/*
* 练习二: 学生对象(姓名,年龄)都有自己的归属地,既然有对应关系。将学生对象和归属地存储到map集合中。
* 注意:同姓名同年龄视为重复的键。按照学生的年龄进行从小到大的排序。 TreeMap。
*
* 如果要对学生按照姓名排序呢?
*/
//1,创建TreeMap集合对象。
Map
//2,添加元素。
map.put(newStudent("lisi", 28), "上海");
map.put(newStudent("wangwu", 22), "北京");
map.put(newStudent("zhaoliu", 24), "成都");
map.put(newStudent("zhouqi", 25), "广州");
map.put(newStudent("wangwu", 22), "南京");
//3,取出所有元素,entrySet()
for(Map.Entry
Studentkey = me.getKey();
Stringvalue = me.getValue();
System.out.println(key+"::"+value);
}
}
}
import java.util.Comparator;
import cn.itcast.domain.Student;
public class ComparatorByName implementsComparator
@Override
publicint compare(Student o1, Student o2) {
inttemp = o1.getName().compareTo(o2.getName());
returntemp==0?o1.getAge() - o2.getAge() : temp;
}
}
import java.util.Map;
import java.util.TreeMap;
public class MapTest {
/**
* @param args
*/
public static void main(String[] args) {
/*
* 练习:
* "werertrtyuifgkiryuiop",获取字符串中每一个字母出现的次数。
* 要求返回结果个格式是 a(1)b(2)d(4)......;
* 思路:
* 1,获取到字符串中的每一个字母。
* 2,用字母取查表,如果查到了该字母对应的次数,就将这个次数+1后重新存回表中。
* 如果没有查到呢?将该字母和1存到表中。
* 3,每一字母都查完表后,表中记录的就是所有字母出现的次数。
*
* 字母和次数之间存在对应关系,而且字母是唯一性的,所以可以使用map集合做表进行查询。
* 通过结果发现 字母有顺序的,所以可以通过map集合中的treemap作为表。
*
*/
String str = "awaa+acr=ebarct,btydui[efgkiryuiop";
str = getCharCount(str);
System.out.println(str);
}
/**
* 获取字符串中的字母出现次数。
*
* @param str
* @return 返回一个每一个字母对应次数的字符串 格式 char1(count)char2(count).....;
*/
public static String getCharCount(String str) {
//1,将字符串转成字符数组。
char[] chs = str.toCharArray();
//2,定义表。treemap.
TreeMap map = new TreeMap();
//3,遍历字符数组。
for (int i = 0; i < chs.length; i++) {
//判断必须是字母。
if(!(chs[i]>='a' && chs[i]<='z' || chs[i]>='A' && chs[i]<='Z')){
continue;
}
//4,将遍历到的字母作为键去查map这个表。获取对应的次数。
Integer value = map.get(chs[i]);
//5,有可能要查询的字母在表中不存在对应的次数,需要判断。
//如果返回是null,说明字母没有对应的次数。就将这个字母和1存储到表中。
if(value == null){
//将字母和1存储。
map.put(chs[i],1);
}else{
//否则,说明有对应的次数对次数自增。将字母和新的次数存储到表中。
value++;
map.put(chs[i],value);
}
/*
//两个if判断,选择哪个都行。
int count = 0;
if(value!=null){
count = value;//用count记录次数。
}
count++;//自增。
map.put(chs[i], count);
*/
}
//将map集合中的键值转成 格式是 a(1)b(2)d(4)......
return mapToString(map);
}
/*
* 将map集合中的键值转成 格式是 a(1)b(2)d(4)......
* map中有很多数据,无论是多少个,什么类型,最终都变成字符串。
* StringBuffer 这个容器就符合这个需求。如果是单线程,建议使用StringBuilder。
*
*/
private static String mapToString(Map map) {
//1,明确容器。
StringBuilder sb = new StringBuilder();
//2,遍历map集合。
for(Character key : map.keySet()){
Integer value = map.get(key);
sb.append(key+"("+value+")");
}
return sb.toString();
}
}