[JAVA基础]集合
一、集合概述
由于数组长度固定,且不能存储对象,所以JAVA出现了集合来存储对象的引用。
JAVA集合继承关系
数据结构知识:
逻辑结构:无序集合 线性结构 树 图
线性表的物理存储:
链式存储(单链表,循环链表,双链表,双循环链表)增删 O(1) 查找O(lgN)
顺序存储(数组) 增删O(N) 查找O(1)
手写单链表
Collection共性方法:
ArrayList al = new ArrayList();
al.add(); //添加元素
al.size(); //获取集合长度
al.remove(); //删除元素
al.clear(); //清空集合
al.contains(); //是否包含某个元素
al.isEmpty(); //集合是否为空
al1.retainAll(al2); //取a1和a2的交集
al.removeAll(al2) //去a1和a2的交集
二、List //(有序,元素可重复) 元素判断用equals()方法
List
|--ArrayList 底层数据结构为数组,有索引,查询修改速度快,增删较慢,常用。
|--LinkedList 底层数据结构为链表,无索引,增删速度快,查询慢。
|--Vector 底层数据结构为数组,有索引。已被ArrayList替代。同步,长度不可变。
常见方法:
add(index,elements); //在指定索引处添加元素
remove(index); // 删除索引处的元素
set(index,element) //; 设置索引处的元素
get(index); // 获取索引处的元素
subList(int from,int to Index); //获取子集,包含头,不包含尾巴
ListIterator(); //List集合特有迭代器,包含特有方法:hasPrevious();pervious();
Iterator是一个接口,在集合的内部,有一个类实现了Iterator接口,以内部类的形式对集合内部元素进行存取操作,好比抓娃娃机的爪子。
Enumeration en = v.Elements;for(en.hasMoreElements ; en.nextElements ; )
程序举例:
1.去重ArrayList中的重复元素 ArrayList
package com.fan.testmain;
import java.util.ArrayList;
import java.util.Iterator;
public class Test3 {
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add("孙悟空");al.add("如来佛");
al.add("观音菩萨");al.add("如来佛");
printArrayList(al);
printArrayList(elementUnique(al));
}
public static ArrayList elementUnique(ArrayList al1) { //封装去重元素方法
ArrayList al2 = new ArrayList(); //建立信的集合接收去重后的元素
for(Iterator it = al1.iterator();it.hasNext() ; ){ //遍历
Object obj = it.next();
if(! al2.contains(obj)) //取出al1中的所有元素,放入新集合中,如果元素存在,则不存
al2.add(obj);
}
return al2;
}
public static void printArrayList(ArrayList al) { //打印集合元素方法
Iterator it = al.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
2.模仿队列 LinkedList 调用removeFirst()和addLast()方法
package com.fan.testmain;
import java.util.Iterator;
import java.util.LinkedList;
public class Test3 {
public static void main(String[] args) {
DuiLie dl = new DuiLie();
dl.add(1); //模拟进入队列
dl.add(2);
dl.add(3);
dl.add(4);
dl.add(5);
dl.add(6);
while(!dl.isEmpty()) { //模拟离开队列
System.out.println(dl.remove());
}
}
}
class DuiLie {
private LinkedList list;
DuiLie() {
this.list = new LinkedList();
}
public void add(Object obj) {
list.add(obj);
}
public Object remove() {
return list.removeFirst();
}
public boolean isEmpty() {
return list.isEmpty();
}
}
三、Set 元素不可重复
|--HashSet:底层数据结构是哈希表。线程不同步。 保证元素唯一性的原理:判断元素的hashCode值是否相同。如果相同,还会继续判断元素的equals方法,是否为true。
|--TreeSet:可以对Set集合中的元素进行排序。默认按照字母的自然排序。底层数据结构是二叉树。保证元素唯一性的依据:compareTo方法return 0。
HashSet
hashCode和equals来完成保证元素唯一性。如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals。
示例
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name=name;
this.age=age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
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 int hashCode()
{
return this.name.hashCode()+this.age;
}
}
class HashSetTest
{
public static void main(String[] args)
{
HashSet h=new HashSet();
h.add(new Person("shenm",10));
h.add(new Person("shenm2",6));
h.add(new Person("shenm1",30));
h.add(new Person("shenm0",10));
h.add(new Person("shenm0",10));
getOut(h);
}
//取出元素
public static void getOut(HashSet h)
{
for (Iterator it=h.iterator(); it.hasNext(); )
{
Person p=(Person)it.next();
sop(p.getName()+"..."+p.getAge());
}
}
//打印
public static void sop(Object obj)
{
System.out.println(obj);
}
}
TreeSet
TreeSet集合底层数据结构为二叉树,元素不可以重复,结合内元素有序(有序即是根据存储元素的大小进行排序,这就需要元素具备比较性,Comparable和Comparator)
程序举例
1、Comparable和Comparator两种方式
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.TreeSet;
/*TreeSet的元素比较
*
*/
public class Test3 {
public static void main(String[] args) {
TreeSet<Person> ts1 = new TreeSet<Person>(); //实现Comparable的方式
ts1.add(new Person("张三",19));
ts1.add(new Person("张三",18));
ts1.add(new Person("张四",18));
ts1.add(new Person("王五",18));
printTs(ts1);
TreeSet<Person> ts2 = new TreeSet<Person>(new MyComp()); //比较器
ts2.add(new Person("alice",19));
ts2.add(new Person("alice",18));
ts2.add(new Person("edison",20));
ts2.add(new Person("edison",18));
printTs(ts2);
}
public static void printTs(TreeSet ts) {
for(Iterator it = ts.iterator();it.hasNext() ; ) {
System.out.println(it.next());
}
}
}
class Person implements Comparable { //创建Person类实现Comparable接口,实现具备比较性
private String name ;
private int age;
Person(String name, int age) {
this.age = age;
this.name = name;
}
public int getAge() {
return this.age;
}
public String getName() {
return this.name;
}
public int compareTo(Object obj) { //overide compareTo()
if(!(obj instanceof Person))
throw new RuntimeException("类型不匹配无法比较");
Person p1 = (Person)obj;
int i = this.name.compareTo(p1.name);
if(i == 0)
return this.age - p1.age;
return i ;
}
public String toString() {
return this.name + "-----" +this.age;
}
}
class MyComp implements Comparator { //自定义实现Comparator接口的类,作为TreeSet(Comparator c)的参数
@Override
public int compare(Object obj1, Object obj2) {
// TODO Auto-generated method stub
Person p1 = (Person)obj1;
Person p2 = (Person)obj2;
int i = p2.getName().compareTo(p1.getName());
if(i == 0)
return p2.getAge() - p1.getAge();
return i;
}
}
2.字符串去重按字典逆序打印
/*将字符串去重按字典逆序排序打印
* 思路:利用TreeSet元素有顺序且不重复的特点
* 将字符串转为字符数组并存入TreeSet集合
* 取出元素放入StringBuffer中
* 调用StringBuffer的reverse()和toString方法
* 打印
*/
package com.fan.testmain;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
public class Test3 {
public static void main(String[] args) {
String s1 = "fdjakfljdaffjklasfjkldqwewqedasfdas";
UniqueSort(s1); //调用排序方法
}
public static void UniqueSort(String s) {
char[] cs = s.toCharArray(); //将字符串转换为字符数组
TreeSet<Character> ts = new TreeSet(); //创建TreeSet集合。
for(char c : cs) { //遍历字符数组,将字符加入TreeSet集合
ts.add(c);
}
Iterator<Character> it = ts.iterator(); //遍历TreeSet集合,将其中元素取出加入到StringBuffer中
StringBuffer sb = new StringBuffer();
while(it.hasNext()) {
sb.append(it.next());
}
String s2 = sb.reverse().toString(); //转换为字符串
System.out.println(s2);
}
}
数据机构:哈希表
哈希表它可以提供快速的插入操作和查找操作。
数组里面存着链表的头节点。散列函数f(key) % len 存储
四、Map(K,V)
|--Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。JDK1.0,效率低。
|--HashMap:底层是哈希表数据结构。允许使用null键null值,该集合是不同步的。JDK1.2,效率高。
|--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给Map集合中的键进行排序。
常用方法
增
Vput(K key,V value);//添加元素,如果出现添加时,相同的键,那么后添加的值会覆盖原有键对应值,并put方法会返回被覆盖的值。
voidputAll(Map <? extends K,? extends V> m);//添加一个集合
删
clear();//清空
Vremove(Object key);//删除指定键值对
判断
containsKey(Objectkey);//判断键是否存在
containsValue(Objectvalue)//判断值是否存在
isEmpty();//判断是否为空
获取
get(Object key);//通过键获取对应的值
size();//获取集合的长度
Collection<V>value();//获取Map集合中所有值,返回一个Collection集合
Set<Map.Entry<K,V>>entrySet();
Set<K> keySet();
遍历取出两种方式
Set<Map.Entry<K,V>>entrySet();
Set<K> keySet();
public static void keySet(HashMap hm) { //通过KeSet获取键集遍历
Set<Integer> s = hm.keySet();
Iterator it = s.iterator();
while(it.hasNext()) {
System.out.println(hm.get(it.next()));
}
}
public static void entrySet(HashMap hm) { //通过映射关系Entry< , >遍历
Set<Entry<Integer,Person>> s1 = hm.entrySet();
Iterator<Entry<Integer,Person>> it1 = s1.iterator();
while(it1.hasNext()) {
Map.Entry<Integer, Person> me= it1.next();
System.out.println(me.getKey()+"------"+me.getValue());
}
}
程序举例
统计字符串出现的次数并排序,输出格式a(2)b(3)c(1)d(4).............
public class Test4 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String s = "abcdabcdabcaba";
System.out.println(stringSort(s));
}
public static String stringSort(String s) {
char[] sc = s.toCharArray(); //转换为字符数组
TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
for(char i : sc) { //遍历字符数组
if(!tm.containsKey(i)) //如果TreeMap中没有该字符元素,则put(i,1)
tm.put(i, 1);
else {
tm.put(i, tm.get(i)+1); //否则值+1
}
}
Iterator<Map.Entry<Character,Integer>> it = tm.entrySet().iterator(); //遍历TreeMAP
StringBuffer sb = new StringBuffer();
while(it.hasNext()) {
Map.Entry<Character, Integer> me = it.next();//通过Entry获取映射
sb.append(me.getKey()+"("+me.getValue()+")"); //通过Entry获取Key和Value
}
String s1 = sb.toString(); //利用StringBuffer转换为字符串
return s1;//返回
}
}
posted on 2017-10-16 20:24 VinceStarry 阅读(160) 评论(0) 编辑 收藏 举报