java基础学习集合学习笔记
2015-08-19 23:40
393 查看
集合
(1)集合的由来和特点A:由来
java中描述数据的最基本单位就是类,为了方便对多个对象进行存储和遍历,
java提供了一种新的存储数据的容器,叫集合类。
B:特点
长度可以变化。
只能存储对象。
(2)集合和数组的区别
A:集合
只能存储对象
长度可以变化
B:数组
可以存储基本数据类型,也可以存储对象类型
长度固定
(3)集合体系的由来
由于每个集合类的数据结构不同,所以,集合会有很多的子类。
但是,这些子类不断的向上抽取共性内容,最终形成了集合体系。
一个体系的学习和使用方式:
学习顶层:顶层定义的是这个体系的共性内容。
使用底层:底层才是具体的存在的实现类。
一、Collection接口中的常见操作
添加元素:
boolean add(Object obj)
删除元素:
void clear()
boolean remove(Object obj)
判断元素:
boolean isEmpty()
boolean contains(Object obj)
长度:
int size()
迭代器:
Iterator iterator()
A:存储字符串
//创建集合对象
Collection c = new ArrayList();
//创建元素对象
String s1 = "haha";
String s2 = "hehe";
String s3 = "xixi";
//把元素对象添加到集合对象中
c.add(s1);
c.add(s2);
c.add(s3);
}
1、概述
迭代是取出集合中元素的一种方式。
对于集合的元素取出这个动作:
当不足以用一个函数来描述,需要用多个功能来体现,所以就将取出这个动作封装成一个对象来描述。就把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内部的元素。那么取出方式就被定义成了内部类。
而每一个容器的数据结构不同,所以取出的动作细节也不一样。但是都具有共性内容: 判断和取出。那么就可以将这些共性抽取。
那么这些内部类都符合一个规则(或者说都抽取出来一个规则)。该规则就是Iterator。通过一个对外提供的方法:iterator();,来获取集合的取出对象。
因为Collection中有iterator方法,所以每一个子类集合对象都具备迭代器。
2、迭代的常见操作
hasNext();//有下一个元素,返回真
next();//取出下一个元素
remove();//移除
注:在迭代时循环中next调用一次,就要hasNext判断一次。
使用:
ArrayList a=newArrayList();//创建一个集合
Iteratorit=a.iterator();//获取一个迭代器,用于取出集合中的元素。
第一种打印方式:
for(Iterator iter = a.iterator();iter.hasNext(); )
{
System.out.println(iter.next());
}
第二种打印方式:
Iteratoriter = a.iterator();
while(iter.hasNext())
{
System.out.println(iter.next());
}
3、迭代注意事项
迭代器在Collcection接口中是通用的,它替代了Vector类中的Enumeration(枚举)。
迭代器的next方法是自动向下取元素,要避免出现NoSuchElementException。
迭代器的next方法返回值类型是Object,所以要记得类型转换。
List 集合
(1)掌握如下体系结构图
List 元素有序,可重复。
|--ArrayList
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。
|--Vector
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
|--LinkedList
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。
(2)List的特有功能
A:添加元素
add(int index,Object obj)
B:删除元素
remove(int index)
C:获取元素
get(int index)
D:列表迭代器
ListIterator listIterator()
E:修改元素
set(int index,Object obj)
ArrayList 集合
案例:
**存储遍历字符串
//创建集合对象
List list = new ArrayList();
//创建元素对象
String s1 = "haha";
String s2 = "hehe";
String s3 = "xixi";
//把元素对象添加到集合对象中
list.add(s1);
list.add(s2);
list.add(s3);
通过迭代器遍历集合元素
Iterator it = list.iterator();
while(it.hasNext())
{
String s = (String) it.next();
System.out.println(s);
}
ListIterator
1、概述
ListIterator是List集合特有的迭代器,是Iterator的子接口。
在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。所以在迭代器时,只能用迭代器的方法操作元素。可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作。如果想要其他的操作,如添加、修改等,就需要使用其子接口:ListIterrator。该接口只能通过List集合的ListIterator方法获取。
2、ListIterator特有的方法
add(obj);//增加
set(obj);//修改为obj
hasPrevious();//判断前面有没有元素
previous();//取前一个元素
**存储遍历自定义对象(Student已经存在,name和age)
List list = new ArrayList();
Student s1 = new Student("唐三角",20);
Student s2 = new Student("孙悟空",25);
Student s3 = new Student("猪八戒",22);
list.add(s1);
list.add(s2);
list.add(s3);
//遍历
Iterator it = list.iterator();
while(it.hasNext())
{
Student s = (Student)it.next();
System.out.println(s.getName()+"***"+s.getAge());
}
for(int x=0; x<list.size(); x++)
{
Student s = (Student) list.get(x);
System.out.println(s.getName()+"***"+s.getAge());
}
(3)List体系下的这个三个集合类用哪一个比较好:
A:如果是要求查询快,就使用ArrayList
B:如果是要求增删多比较多,就使用LinkedList
C:如果涉及多线程安全问题,就使用Vector
(4)注意:ArrayList的contains方法底层依赖的是equals方法。
枚举:
就是Vector特有的取出方式。Vector有三种取出方式。
其实枚举和迭代是一样的。因为枚举的名称以及方法的名称都过长。所以被迭代器取代了。
特有方法:
addElement(obj);//添加元素,相当于add(obj);
Enumerationelements();//Vector特有取出方式(枚举)
hasMoreElements();//相当于Iterator的hasNext()方法
nextElements();//相当于Iterator的next()方法
例:
Vector v=new Vector();
for(Enumeration e=v.elements();e.hasMoreElements();)
{
System.out.println(e.nextElements());
}
LinkedList
LinkedList:底层使用的是链表数据结构。特点:增删速度很快,查询稍慢。
特有方法:
1、增
addFirst();
addLast();
2、获取
//获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException
getFirst();
getLast();
3、删
//获取元素,并删除元素。如果集合中没有元素,会出现NoSuchElementException
removeFirst();
removeLast();
在JDK1.6以后,出现了替代方法。
1、增
offFirst();
offLast();
2、获取
//获取元素,但是不删除。如果集合中没有元素,会返回null。
peekFirst();
peekLast();
3、删
//获取元素,并删除元素。如果集合中没有元素,会返回null。
pollFirst();
pollLast();
Set 集合
HasSetHashSet:线程不安全,存取速度快。
可以通过元素的两个方法,hashCode和equals来完成保证元素唯一性。如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals。
注意:HashSet对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。
示例:
public class Student
{
private String name;
private int age;
public Student(){}
public Student(String name,int age)
{
this.name = name;
this.age = age;
}
//get/set...
public int hashCode()
{
return this.name.hashCode()+this.age*11;
}
public boolean equlas(Object obj)
{
if(this==obj)
{
return true;
}
if(!(obj instanceof Student))
{
return false;
}
Student s = (Student)obj;
return this.name.equals(s.name) && this.age==s.age;
}
}
public class HashSetDemo
{
public static void main(String[] args)
{
HashSet<Student> hs = new HashSet<Student>();
Student s1 = new Student();
Student s2 = new Student();
Student s3 = new Student();
hs.add(s1);
hs.add(s2);
hs.add(s3);
//遍历
}
}
TreeSet
1、特点
a、底层的数据结构为二叉树结构
b)可对Set集合中的元素进行排序,是因为:TreeSet类实现了Comparable接口,该接口强制让增加到集合中的对象进行了比较,需要复写compareTo方法,才能让对象按指定需求(如人的年龄大小比较等)进行排序,并加入集合。
java中的很多类都具备比较性,其实就是实现了Comparable接口。
注意:排序时,当主要条件相同时,按次要条件排序。
Tree排序的两种方式
1)第一种排序方式:自然排序
让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。这种方式也被称为元素的自然顺序,或者叫做默认顺序。
示例:
import java.util.*;
//学生类
class Student implements Comparable
{
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;
}
//复写hashCode以便HashSet集合调用
public int hashCode()
{
return name.hashCode()+age;
}
//复写equals以便HashSet集合和集合中一些比较方法调用
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException();
Student s = (Student)obj;
return this.name.equals(s.name)&&this.age==s.age;
}
//复写compareTo以便TreeSet集合调用
public int compareTo(Object obj)
{
Student s=(Student)obj;
if(this.age==s.age)
return this.name.compareTo(s.name);
return this.age-s.age;
//return new Integer(this.age).compareTo(new Integer(s.age));
}
}
class TreeSetTest
{
public static void main(String[] args)
{
TreeSet<Student> t=new TreeSet<Student>();
t.add(new Student("wo1",12));
t.add(new Student("wosj",2));
t.add(new Student("wo1sdj",12));
t.add(new Student("wo6sd",12));
t.add(new Student("wo",22));
for (Iterator<Student> it=t.iterator(); it.hasNext(); )
{
Student s=it.next();
System.out.println(s.getName()+"....."+s.getAge());
}
}
}
2)第二种方式:比较器
当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让集合自身具备比较性。
在集合初始化时,就有了比较方式。定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
比较器构造方式:定义一个类,实现Comparator接口,覆盖compare方法。
当两种排序都存在时,以比较器为主。
示例:
/*
需求:
往TreeSet集合中存储自定义对象学生。
想按照学生的年龄进行排序。
*/
import java.util.*;
//学生类
class Student implements Comparable
{
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;
}
//复写hashCode以便HashSet集合调用
public int hashCode()
{
return name.hashCode()+age;
}
//复写equals以便HashSet集合和集合中一些比较方法调用
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException();
Student s = (Student)obj;
return this.name.equals(s.name)&&this.age==s.age;
}
//复写compareTo以便TreeSet集合调用
public int compareTo(Object obj)
{
Student s=(Student)obj;
if(this.age==s.age)
return this.name.compareTo(s.name);
return this.age-s.age;
//return new Integer(this.age).compareTo(new Integer(s.age));
}
}
class TreeSetTest
{
public static void main(String[] args)
{
TreeSet<Student> t=new TreeSet<Student>(new LenCompare());
t.add(new Student("wo1",12));
t.add(new Student("wosj",2));
t.add(new Student("wo1sdj",12));
t.add(new Student("wo6sd",12));
t.add(new Student("wo",22));
for (Iterator<Student> it=t.iterator(); it.hasNext(); )
{
Student s=it.next();
System.out.println(s.getName()+"....."+s.getAge());
}
}
}
//定义一个比较器,以姓名长度为主要比较
class LenCompare implements Comparator<Student>
{
public int compare(Student s1,Student s2)
{
int num=new Integer(s1.getName().length()).compareTo(new Integer(s2.getName().length()));
if (num==0)
{
return new Integer(s1.getAge()).compareTo(s2.getAge());
}
return num;
}
}
5:总结
如果你使用的集合要保证元素唯一:Set不需要排序:HashSet
需要排序:TreeSet
如果你使用的集合不用保证元素唯一:List
查询:ArrayList
修改:LinkedList
线程不安全:Vector
小技巧:
Array:说明底层数据结构是数组,查询快,增删慢
Link:说明底层数据结构是链表,查询慢,增删快
Hash:说明底层数据结构是哈希表,保证元素唯一,要依赖hashCode和equals。
Tree:说明底层数据结构是二叉树,有两种方案保证唯一和排序:
A:Comparable -- compareTo
B:Comparator -- compare
Map 集合
一、概述1、简述:
Map<K,V>集合是一个接口,和List集合及Set集合不同的是,它是双列集合,并且可以给对象加上名字,即键(Key)
2、特点:
1)该集合存储键值对,一对一对往里存
2)要保证键的唯一性。
二、Map集合的子类
Map
|--Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。JDK1.0,效率低。
|--HashMap:底层是哈希表数据结构。允许使用null键null值,该集合是不同步的。JDK1.2,效率高。
|--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键进行排序。
Map和Set很像。其实Set底层就是使用了Map集合。
三、Map集合的常用方法
A:添加元素
put(Object key,Object value):把键值对元素添加到Map集合中
B:删除元素
remove(Object key):删除键为key的元素
C:判断功能
containsKey(Object key):判断Map集合中是否有键为key的键值
containsValue(Object value):判断Map集合中是否有值为value的值
D:获取元素
get(Object key):根据键获取值
keySet():获取Map集合的键的Set集合
values():获取Map集合的值的Collection集合
entrySet():获取Map集合的键值对的集合
E:长度
size():Map集合中键值对元素的个数
遍历的思路:
思路1:
获取键值对的集合 keySet()
遍历键集合,获取到每个键 Iterator hasNext(),next()
通过键去找自己的值 get()
思路2:
键值对的映射项Map.Entry是Map做好的:
Map.Entry<Key,Value>
键值对集合 entrySet()
遍历键值对集合,获取到每个键值对的映射项Map.Entry对象 Iterator hasNext(),next()
通过键值对的映射项Map.Entry对象获取键和值 getKey(),getValue()
案例演示:
键和值都是字符串:
Map<String,String> map = new HashMap<String,String>();
map.put("张三", "北京");
map.put("李四", "上海");
map.put("王五", "天津");
map.put("赵六", "重庆");
map.put("田七", "陕西");
//方式1
Set<String> keySet = map.keySet();
Iterator<String> keyIt = keySet.iterator();
while(keyIt.hasNext())
{
String key = keyIt.next();
String value = map.get(key);
System.out.println(key+"***"+value);
}
//方式2
Set<Map.Entry<String,String>> meSet = map.entrySet();
Iterator<Map.Entry<String,String>> meIt = meSet.iterator();
while(meIt.hasNext())
{
Map.Entry<String,String> me = meIt.next();
String key = me.getKey();
String value = me.getValue();
System.out.println(key+"***"+value);
}
(3)HashMap
是如何保证键的唯一性:
通过自定义对象的hashCode方法和equals方法。
代码体现:键是自定义对象,值是字符串
前提:Student重写了hashCode方法和equals方法。
HashMap<Student,String> hm = new HashMap<Student,String>();
Student s1 = new Student("科比", 20);
Student s2 = new Student("霍华德", 22);
Student s3 = new Student("易建联", 25);
Student s4 = new Student("乔丹", 24);
Student s5 = new Student("林书豪", 23);
Student s6 = new Student("易建联", 25);
Student s7 = new Student("乔丹", 24);
hm.put(s1,"北京");
hm.put(s2,"上海");
hm.put(s3,"重庆");
hm.put(s4,"天津");
hm.put(s5,"武汉");
hm.put(s6,"深圳");
hm.put(s7,"石家庄");
//遍历
Set<Student> set = hm.keySet();
Iterator<Student> it = set.iterator();
while(it.hasNext())
{
Student key = it.next();
String value = hm.get(key);
System.out.println(key.getName()+"***"+key.getAge()+"***"+value);
}
(4)TreeMap
是如何保证键的唯一性和排序的:
集合具备比较性:Comparator -- compare
元素具备比较性:Comparable -- compareTo
(5)LinkedHashSet和LinkedHashMap
通过链表保证有序
通过哈希保证唯一
LinkedHashSet:保证元素有序,唯一
LinkedHashMap:保证键有序,唯一
(6)HashMap和Hashtable的区别:
A:Hashtable是线程安全的,效率低。HashMap是线程不安全的,效率高。
B:Hashtable的键和值都不能为null。HashMap可以允许null键和null值。
7:工具类的使用
(1)对数组操作的ArraysA:static String toString(数组)
B:static void sort(数组)
可以对对象数组进行排序。
两种方式:
元素具备比较性
Arrays的sort方法具备比较性
C:static int binarySearch(数组,值)
前提:数组有序
D:static <T> List<T> asList(T... t)
(2)对集合操作的Collections
A:static void sort()
B:static void reverse()
C:static int binarySearch(集合,值)
相关文章推荐
- JAVA_SE基础——26.[深入解析]局部变量与成员变量的区别
- Java心得17
- Struts2-Ajax无刷新显示信息
- java内存结构(运行时数据区域)
- Java-Thread (线程)
- ajax+json+java
- java无加减乘除运算符实现加法
- java的枚举类型
- Spring-boot 学习笔记(1)
- Java-Exception(异常)
- JavaFX2 - 文本可复制的Label
- ubuntu下jdk区别与切换
- install hadoop dev plugin in eclipse
- Java泛型总结
- Eclipse插件使用links目录的用法
- 直接在sublime test3中编译Java源程序
- Java的内存回收机制
- Spring & 配置
- Java集合的遍历方法
- Ubuntu安装Sun JDK及如何设置默认java JDK