黑马程序员 集合框架
来源:互联网 发布:深圳java外包公司 编辑:程序博客网 时间:2024/05/10 03:02
集合框架
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
1.为什么出现集合类?
面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。
2.数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但长度是固定的,集合长度是可变的,数组中可以存储基本数据类型,集合只存储对象。
3.集合类的特点
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。集合中存储的都是对象的引用(地址)
4.出现多个容器的原因:因为每一个容器对数据的存储方式都不同,这个存储方式称为数据结构。
5.集合框架的共性方法
ArrayList a1=new ArrayList();
//添加元素,a1.add(Object obj);add方法的参数类型是Object,以便于接收任意类型对象
a1.add(“java01”);
a1.add(“java02”);
a1.add(“java03”);
//删除元素
a1.remove(“java02”);
a1.clear();//清空集合
//判断元素
a1.contains(“java03”);
a1.isEmpty();//判断集合是否为空
//获取集合长度
a1.size();
ArrayList a2=new ArrayList();
a2.add(“java01”);
a1.retainAll(a2);//取交集,a1中只会保留和a2中相同的元素。
a1.removeAll(a2)//去交集,a1中只会保留和a2中不相同的元素。
6.什么是迭代器?
其实就是集合的取出元素的方式。
(1)当取出这个动作不足以用一个函数来描述,需要用多种功能来体现,那么就把取出这个动作封装成一个对象,通过内部类来描述对象,这样可以直接访问集合内部的元素。
(2)每一个容器的数据结构不同,所以取出的动作细节也不一样。但是都具有共性内容: 判断和取出。那么就可以将这些共性抽取。
(3)这些内部类都符合一个规则,该规则是Iterator。如何获取集合的取出对象呢?通过一个对外提供的方法。Iterator();
(4)Collection中有iterator(),所以每一个子类集合对象都具备迭代器。
(5)迭代器的常见操作
hasNext();//有下一个元素,返回真
next();//取出下一个元素
remove();//移除
有两种迭代方式:
第一种:
ArrayList a1=new ArrayList();//创建一个集合
Iterator it=a1.iterator();//获取一个迭代器,用于取出集合中的元素。
while(it.hasNext())
{
sop(it.next());
}
第二种:
ArrayList a1=new ArrayList();//创建一个集合
for(Iterator it=a1.iterator();it.hasNext();)
{
sop(it.next)
}
(6)迭代注意事项
a.迭代器在Collcection接口中是通用的,它替代了Vector类中的Enumeration(枚举)。
b.迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException。
c.迭代器的next方法返回值类型是Object,所以要记得类型转换。
7.List集合
(1)Collection中常见的两种集合:
List:元素是有序的,元素可以重复,因为该集合体系有索引。
ArrayList:底层的数据结构使用的是数组结构;特点:查询速度 快,增删速度慢,线程不同步。ArrayList的长度是 可变化的(默认长度是10),当元素超过默认长度, ArrayList会自动延长50%的长度
LinkeList:底层使用的是链表数据结构;特点:增删速度快,
查询速度慢
Vector:底层是数组数据结构,线程同步。增删,查询都很慢,被 ArrayList替代。Vector的长度是可变化的(默认长度是 10),当元素超过默认长度,Vector会延长100%
Set:元素是无序的,元素不可以重复。
(2)List特有方法:凡是可以操作角标的方法都是该体系特有的方法。
增:
add(index,element);//在指定位置添加元素
addAll(index,Collection);//在指定位置添加集合元素
删:
remove(index);//删除指定位置的元素
改:
set(index,element);//修改指定位置的元素
查:
get(index);//获取角标元素
subList(from,to);//获取部分元素
listIterator();//通过迭代方法获取全部元素
indexOf(obj);//获取对象位置,如果没有该对象则返回-1。
(3)ListIterator是Iterator的子接口,是List集合特有的迭代器。因为Iterator方法是有限的,同时在迭代时,不可以通过集合对象的方法操作集合中的元素。否则会发生ConcurrentModificationException异常。所以可以通过ListIterator方法拓展对元素的操作。(注意:该接口只能通过List集合的listIterator方法获取)
(4)ListIterator特有的方法
add(obj);//增加
set(obj);//修改
hasPrevious();//判断前面有没有元素
previous();//取前一个元素
(5)Vecter
枚举: 就是Vector特有的取出方式。Vector有三种取出方式。
其实枚举和迭代是一样的。因为枚举的名称以及方法的名称都过长。所以被迭代器取代了。
特有方法:
Vecter v=new Vector();
v.add(“java01”);
Enumeration en=v.elements();
While(en.hasMoreElements())
{
sop(en.nextElements());
}
hasMoreElements();//相当于Iterator的hasNext()方法
nextElements();//相当于Iterator的next()方法
8.LinkedList
特有方法:
addFirst();//将元素添加在最前面
addLast();//将元素添加在最后面
getFirst();//获取第一个元素
getLast();//获取最后一个元素
removeFirst();//获取第一个元素并从集合中删除该元素
removeLast();//获取最后一个元素并从集合中删除该元素
(注意:get方法和remove方法中,如果集合没有元素,则会出现NoSuchElementException)
使用方法:
//创建一个LinkedList 类型的集合对象link
LinkedList link=new LinkedList();
link.addFirst(“java01”);
link.addLast(“java02”);
sop(link.getFirst());
sop(link.getLast());
sop(link.removeFirst());
sop(link.size());
sop(link.getLast());
在JDK1.6出现替代方法
offerFirst();//添加元素
offerLast();
peekFirst();//获取元素,但不删除元素
peekLast();
pollFirst();//获取元素,而且删除元素
pollLast();
(注意:peek方法和poll方法中,如果集合没有元素,则会返回null)
练习一:
<span style="font-size:14px;">//使用LinkedList模拟一个堆栈或者队列数据结构队import java.util.*;class DuiLie {private LinkedList link;DuiLie(){link=new LinkedList();}public void myAdd(Object obj){link.addFirst(obj);//先进,在首位添加元素}public Object myRemove(){return link.removeLast();//先出,删除末尾的元素}public boolean isNull(){return link.isEmpty();//判断集合是否为空}}class LinkedListTest{public static void main(String[] args) {DuiLie d=new DuiLie();d.myAdd("java01");d.myAdd("java02");d.myAdd("java03");d.myAdd("java04");while(!d.isNull()){System.out.println(d.myRemove());}}}</span>
练习二:
//去除ArrayList集合的重复元素。import java.util.*;class ArrayListTest{public static ArrayList singleElement(ArrayList a1){ArrayList a2=new ArrayList();//创建集合a2Iterator it=a1.iterator();//获取a1迭待器while(it.hasNext()){/*判断a2集合里是否已存在该元素,不存在则将元素存在a2集合里*/Object obj=it.next();if(!a2.contains(obj))a2.add(obj);}return a2;}public static void main(String[] args) {ArrayList a1=new ArrayList();//创建集合a1//添加元素a1.add("java01");a1.add("java02");a1.add("java01");a1.add("java02");a1.add("java03");System.out.println(a1);a1=singleElement(a1);//调用函数System.out.println(a1);}}
练习三:
/*将自定义对象作为元素存到ArrayList集合中,并去除重复元素 。*/import java.util.*;class Person{private String name;private int age;Person(String name,int age){this.name=name;this.age=age;}/*Object里面的equals方法是比较对象的地址值,然而每个对象的地址值都不一样,不能够作为本程序的判断方法。所以要按照自身的需求覆写Object里面的equals方法作为contains方法里的判断条件。注意:euqals方法是自动被调用的。*/public boolean equals(Object obj){if(!(obj instanceof Person))return false;Person p=(Person)obj;return this.name.equals(p.name) && this.age==p.age;}public String getName(){return name;}public int getAge(){return age;}}class ArrayListTest2 {public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args) {ArrayList a1=new ArrayList();a1.add(new Person("name1",1));a1.add(new Person("name1",1));a1.add(new Person("name2",2));a1.add(new Person("name2",2));a1.add(new Person("name3",3));a1.add(new Person("name3",3));a1=singleElement(a1);Iterator it=a1.iterator();while(it.hasNext()){/*因为迭代器里面返回的都是Object,要使用Person里面的方法,就要对象向下转型Object obj=it.next()Person p=(Person)obj;即:Person p=(Person)it.next()*/Person p=(Person)it.next();sop(p.getName()+"::"+p.getAge());}}public static ArrayList singleElement(ArrayList a1){ArrayList a2=new ArrayList();Iterator it=a1.iterator();while(it.hasNext()){Object obj=it.next();if(!a2.contains(obj))a2.add(obj);}return a2;}}
9.
(1)Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复。
(a)HashSet:底层数据结构是哈希表。
(b)HashSet是如何保证元素唯一性的呢?
是通过元素的两个方法,hashCode和equals来完成。如果元素的HashCode值相同,才会判断equals是否为true。如果元素的HashCode值不同,不会调用equals。注意,对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。
(c)TreeSet:可以对Set集合的元素进行排序,底层数据结构是二叉树(小的存左,大的存右),保证元素唯一性的依据:compareTo方法return 0。(注意:排序时,当主要条件相同时,一定判断一下次要条件)
TreeSet排序的第一种方式:让元素自身具备比较性,元素需要实现Comparable接口,覆盖compareTo方法。这种方式也成为元素的自然顺序,或者叫做默认顺序。
TreeSet排序的第二种方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性。
(2)集合的功能和Collection是一致的。
10.泛型
(1)概述:JDK1.5版本以后出现新特性,用于解决安全问题,是一个类型安全机制。
(2)好处
(a)将运行时期出现问题ClassCastException,转移到了编译时期,方便于程序员解决问题,让运行时问题减少,安全。
(b)避免了强制转换的麻烦。
(3)泛型格式:通过<>来定义要操作的引用数据类型。
(4)在使用java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见,只要见到<>就要定义泛型。
(5)什么时候定义泛型类?
当类中要操作的引用数据类型不确定的时候。
格式:
class Xxx<QQ>
{}
class Yyy
{ public static void main(String[] args)
{
Xxx<QQ> x=new Xxx<QQ>();
}
}
(6)泛型类定义的泛型在整个类中有效,如果被方法使用,那么泛型的对象明确要操作具体类型后,所有要操作的类型已经固定。
(7)为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。
格式:public <T> void show(T t){}
(8)静态方法泛型的特殊之处:静态方法不可以访问类上定义的泛型。如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。
格式:public static <T> void show(T t){}
(9)泛型接口:
格式:
Interface Inter<T>
{void show(T t);}
Class InterImpl implements Inter<String>
{
public void show(String t){}
}
(10)泛型限定
?通配符,也可以理解为占位符。
? extends E:可以接收E类型或者E的子类型,上限。
? super E:可以接收E类型或者E的父类型,下限。
局限性:不可以使用引用数据类型的特有方法。
import java.util.*;class GenericDemo {public static void main(String[] args) {//添加了比较器,按照比较器的要求排序//a1集合的元素为Student类型TreeSet<Student> a1=new TreeSet<Student>(new Comp());a1.add(new Student("stu01"));a1.add(new Student("stu03"));a1.add(new Student("stu02"));Iterator<Student> it=a1.iterator();while(it.hasNext()){System.out.println(it.next().getName());}//a2集合的元素为Worker类型TreeSet<Worker> a2=new TreeSet<Worker>(new Comp());a2.add(new Worker("work01"));a2.add(new Worker("work03"));a2.add(new Worker("work02"));Iterator<Worker> it2=a2.iterator();while(it2.hasNext()){System.out.println(it2.next().getName());}}}class Person{private String name;Person(String name){this.name=name;}public String getName(){return name;}}class Student extends Person//继承关系{Student(String name){super(name);//调用父类的构造方法}}class Worker extends Person//继承关系{Worker(String name){super(name);}}class Comp implements Comparator<Person>//比较器{public int compare(Person p1,Person p2){return p1.getName().compareTo(p2.getName());}}
11.Map集合
(1)概述:该集合存储键值对,一对一对往里存,而且要保证键的唯一性。
(2)方法
添加:
put(K key, V value)
/*如果出现添加时,相同的值,那么后添加的值会覆盖原有键对应的值,并put方法会返回被覆盖值。*/
删除:
clear()
判断:
containsKey(Object key)
containsValue(Object value)
isEmpty()
获取:
get(Object key)
/*可以通过get方法的返回值来判断一个键是否存在,通过返回null来判断*/
size()
values()
(3)Map的三部分
Hashtable:底层是哈希表数据结构,不可以存入null键null值,该集合是线程同步的,效率低,jdk1.0。
HashMap:底层是哈希表数据结构,允许使用null键,该集合是不同步的,效率高,jdk1.2。
TreeMap:底层是二叉树数据结构,线程不同步,可以用于给map集合中的键进行排序。
(小知识:Set底层就是使用了Map集合)
(4)Map集合的两种取出方式
keySet:将Map中所有的键存入到Set集合,因为Set具备迭代器。
所以可以通过迭代方式取出所有的键,在根据get方法,获取每一个键对应的值。
Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了Set集合中,而这个关系的数据类型是:Map.Entry。(其实Entry也是一个接口,它是Map接口中的一个内部接口)
练习一:
/*keySet:将Map中所有的键存入到Set集合,因为Set具备迭代器。所以可以通过迭代方式取出所有的键,在根据get方法,获取每一个键对应的值。*/import java.util.*;class KeySetDemo {public static void main(String[] args) {//创建Map集合并定义泛型Map<String,String> map=new HashMap<String,String>();map.put("04","lisi04");map.put("02","lisi02");map.put("01","lisi01");map.put("03","lisi03");//将Map集合中的键存放在Set集合中Set<String> keySet=map.keySet();//获取Set集合的迭待器Iterator<String> it=keySet.iterator();while(it.hasNext()){String key=it.next();String value=map.get(key);//通过键获取该键对应的值System.out.println("key:"+key+";value:"+value);}}}练习二
/*Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了Set集合中,而这个关系的数据类型是:Map.Entry。*/import java.util.*;class EntrySetDemo {public static void main(String[] args) {//创建Map集合Map<String,String> map=new HashMap<String,String>();map.put("04","lisi04");map.put("02","lisi02");map.put("01","lisi01");map.put("03","lisi03");//将映射关系存放在Set集合里面Set<Map.Entry<String,String>> entrySet=map.entrySet();//获取Set集合的迭待器Iterator<Map.Entry<String,String>> it=entrySet.iterator();while(it.hasNext()){//提取映射关系,直接获取键值和键值对应的值Map.Entry<String,String> me=it.next();String key=me.getKey();String value=me.getValue();System.out.println("key:"+key+";value:"+value);}}}
练习三
/*1.描述一个学生2.定义map容器,将学生作为键,地址作为值,存入。3.获取map集合中的元素。*/import java.util.*;class MapTest {public static void main(String[] args) {HashMap<Student,String> hm=new HashMap<Student,String>();//注意Map集合添加元素方法是put,而不是addhm.put(new Student("lisi01",21),"beijing");hm.put(new Student("lisi03",23),"guangdong");hm.put(new Student("lisi02",22),"shanghai");//第一种取出方式:取出键!Set<Student> keySet=hm.keySet();Iterator<Student> it=keySet.iterator();while(it.hasNext()){Student stu=it.next();String addr=hm.get(stu);System.out.println("Student:"+stu+"...addr:"+addr);}//第二种取出方式:取出映射关系!Set<Map.Entry<Student,String>> entrySet=hm.entrySet();Iterator<Map.Entry<Student,String>> it2=entrySet.iterator();while(it2.hasNext()){Map.Entry<Student,String> me=it2.next();Student stu=me.getKey();String addr=me.getValue();System.out.println("Student:"+stu+"_ _ _addr:"+addr);}}}class Student{private String name;private int age; Student(String name,int age){this.name=name;this.age=age;}public String getName(){return name;}public int getAge(){return age;}public String toString(){return name+":"+age;}//自定义对象需要覆写hashCode方法和equals方法public int hashCode(){return name.hashCode()+age*34;}public boolean equals(Object obj){if(!(obj instanceof Student))throw new ClassCastException("类型不匹配");Student s=(Student)obj;return this.name.equals(s.name) && this.age==s.age;}}
12.方法的可变参数
当函数的参数列表是同一类型,那么可以将参数隐式地封装在数组里
13.StaticImport 静态导入
(1)当类名重名时,需要指定具体的包名;
当方法重名时,指定具备所属的对象或者类。
(2)import static java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。
(3)import static java.lang.System.*;//导入了System类中所有静态成员
14.Date
Date d=new Date();
System.out.println(d);//打印的时间看不懂
SimpleDateFormat adf=new SimpleDateFormat(“yyyy年MM月dd日 E hh:mm:ss”);//将模式封装到SimpleDateFormat对象中。
String time=adf.format(d);//调用format方法让模式格式化指定Date对象
15.Calendar
Calendar c=Calendar.getInstance();//获取对象
c.set(2012,2,1);//设置时间:2012年3月1日 (0~11表示1~12月)
c.add(Calendar.DAY_OF_MONTH,-1)//3月1日往前推一天就是2月的最后一天。
c.add(Calendar.MONTH)//获取年
c.add(Calendar.DAY_OF_WEER)//获取星期
c.add(Calendar.YEAR)//获取年
16.Math
(1)double d=Math.ceil(16.34);//返回大于指定数据的最小整数。
(2)double d1=Math.floor(12.34)//floor返回小于指定数据的最大整数。
(3)long l=Math.round(12.54);//四舍五入
(4)double d2=Math.pow(2,3);//2的3次方
(5)Random r=new Random();
for(int x=0;x<10;x++)
{
//随机取出10个包含10不包含包0的整数
//int d=(int)(Math.random()*10+1);
int d=r.nextInt(10)+1;
sop(d);
}
- 黑马程序员:集合框架
- 黑马程序员-集合框架
- 黑马程序员-集合框架
- 黑马程序员:集合框架
- 黑马程序员-----集合框架
- 黑马程序员: 集合框架
- 黑马程序员-集合框架
- 黑马程序员--集合框架
- 黑马程序员- 集合框架
- 黑马程序员-集合框架
- 黑马程序员--------集合框架
- 黑马程序员----集合框架
- 黑马程序员 集合框架
- 黑马程序员 集合框架
- 黑马程序员:集合框架
- 黑马程序员-集合框架
- 黑马程序员----------------------集合框架
- 黑马程序员 集合框架
- Indy的TCPServer到底能支持多少个连接
- 关于堆排序的了解和实现
- mongodb 学习笔记 06 -- mongod配置文件
- LeetCode 题解(130): Bitwise AND of Numbers Range
- 成功测试opencv1.0+vc6.0
- 黑马程序员 集合框架
- Day1 学习记录
- 安卓恶意代码分析
- 【UNIX网络编程】 22~25 高级UDP套接字编程、高级SCTP 套接字编程、带外数据、信号驱动I/O
- Java 运行时监控,第 1 部分: Java 系统运行时性能和可用性监控
- 树莓派上的立体视觉和深度知觉
- Java 运行时监控,第 2 部分: 编译后插装和性能监控
- Java 运行时监控,第 3 部分: 监控应用程序生态系统的性能与可用性
- Leecode Gas Station