17、集合框架
概述
为什么出现集合类
面对对象语言对事物的体现都是以对象的形式,所以为了方便多个对象的操作,就对对象进行存储,集合就是存储对象的最常用的一种形式
数组和集合类同是容器
数组虽然可以存储对象,但长度是固定的,集合长度是可变的,数组中可以存储基本数据类型,集合只能存储对象
集合类的特点
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象
Collection定义了集合框架的共性功能。
1,添加
add(e);
addAll(collection);
2,删除
remove(e);
removeAll(collection);
clear();
3,判断。
contains(e);
isEmpty();
4,获取
iterator();
size();
5,获取交集。
retainAll();
6,集合变数组。
toArray();
add方法的参数类型是Object。以便于接收任意类型对象。
集合中存储的都是对象的引用(地址)
7、迭代器
其实就是集合取出元素的方式,把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内部的元素,那么取出方式就被定义成内部类。而每一个容器数据结构不同,所以取出的动作细节也不一样,但是都是共性内容。判断和取出,可以将这些共性抽取。
Iterator:那么这些内部类都符合一个规则,该规则是Iterator
package days7;
import java.util.*;
public class Collectons
{
public static void main(String[]args) throws Exception
{
ArrayList al=new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
sop(al);
sopt("size"+al.size());
al.remove("java02");
sop(al);
sopt("java03是否存在:"+al.contains("java03"));
ArrayList al2=new ArrayList();
al2.add("java01");
al2.add("java02");
al2.add("java03");
al2.add("java04");
al.retainAll(al2);
sop(al);
al.clear();
sopt("集合是否为空:"+al.isEmpty());
}
public static void sop(ArrayList al)
{
Iterator it=al.iterator();
while(it.hasNext())
{
sopt(it.next());
}
}
public static void sopt(Object obj)
{
System.out.println(obj);
}
}
List集合共性方法
Collection
List:元素是有序的,元素可以重复,因为该集合体系有索引
Set:元素是无序的,元素不可以重复
List:特有方法:凡是可以操作角标的方法都是该体系特有的方法
增:add(index,element)
删:remove(index)
改:set(index,element)
查:get(index)subList(from,to)
ListIterator()
查:get(index) subList(from,to)
ListIterator()
package days7;
import java.util.*;
//import javax.swing.text.html.HTMLDocument.Iterator;
public class Lists
{
public static void main(String args[])
{
ArrayList al=new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
al.remove(2);
al.set(2, "sdk");
sop(al.get(1));
sop(al);
System.out.println();
for(int x=0;x<al.size();x++)
{
sop(al.get(x));
}
System.out.println();
Iterator it=al.iterator();
while(it.hasNext())
{
sop(it.next());
}
System.out.println();
sop(al.subList(1, 3));
sop(al.indexOf("Java04"));
}
public static void sop(Object obj)
{
System.out.print(obj);
System.out.print(" ");
}
}
package days7;
import java.util.*;
public class ListIt
{
public static void main(String[]args)
{
ArrayList al=new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
Iterator it = al.iterator();
while(it.hasNext())
{
Object obj=it.next();
if(obj.equals("java02"))
{
it.remove();
}
}
sop(al);
System.out.println();
ListIterator it2=al.listIterator();
while(it2.hasPrevious())
{
sop("pre::"+it2.previous());
}
//sop("hasNext():"+li.hasNext());
//sop("hasPrevious():"+li.hasPrevious());
System.out.println();
while(it2.hasNext())
{
Object obj=it2.next();
if(obj.equals("java03"))
it2.set("java06");
}
sop(al);
}
public static void sop(Object obj)
{
System.out.print(" "+obj);
}
}
List集合具体对象的特征
元素是有序的,元素可以重复,因为该集合体系有索引
List:
ArrayList:底层用的是数组数据结构,特点:查询速度很快,但是增删稍慢
LinkedList:底层用的是链表数据结构。特点:增删很快,查询速度稍慢,线程不同步
Vector:底层是数组数据结构,线程同步,被ArrayList淘汰
package days7;
import java.util.*;
public class Vectors
{
public static void main(String[]args)
{
Vector v=new Vector();
v.add("java01");
v.add("java02");
v.add("java03");
v.add("java04");
Enumeration en = v.elements();
while(en.hasMoreElements())
{
System.out.println(en.nextElement());
}
}
}
枚举就是Vector特有的取出方式,发现枚举和迭代器很像。因为枚举的名称以及方法的名称都过长。所以被迭代器取代,枚举就郁郁而终了。
LinkedList
LinkedList:特有方法:
addFirst();
addLast();
getFirst();
getLast();
获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException
removeFirst();
removeLast();
获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementException
在JDK1.6出现了替代方法。
offerFirst();
offerLast();
peekFirst();
peekLast();
获取元素,但不删除元素。如果集合中没有元素,会返回null。
pollFirst();
pollLast();
获取元素,但是元素被删除。如果集合中没有元素,会返回null。
练习代码:
package days7;
import java.util.*;
public class LinkedList1
{
public static void main(String[]args)
{
LinkedList link=new LinkedList();
link.addLast("java01");
link.addLast("java02");
link.addLast("java03");
link.addLast("java04");
sop(link);
trims();
sop(link.getFirst());
trims();
sop(link.getLast());
trims();
sop(link.removeLast());
trims();
sop(link);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void trims()
{
System.out.println();
}
}
使用LinkedList模拟一个堆栈或者队列数据结构。
堆栈:先进后出 如同一个杯子。
队列:先进先出 First in First out FIFO 如同一个水管。
package days7;
import java.util.*;
public class LinkTest
{
public static void main(String[]args)
{
LinkedList link=new LinkedList();
link.addFirst("java01");
link.addFirst("java02");
link.addFirst("java03");
link.addFirst("java04");
while(!link.isEmpty())
{
sop(link.removeLast());
}
sop(link);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
需求:去除ArrayList集合中的重复元素。
package days7;
import java.util.*;
public class ArrayList1
{
public static void main(String[]args)
{
ArrayList al=new ArrayList();
al.add("java01");
al.add("java02");
al.add("java01");
al.add("java02");
al.add("java01");
al.add("java03");
sop(al);
al=move(al);
sop(al);
}
public static ArrayList move(ArrayList al)
{
ArrayList al2=new ArrayList();
Iterator it=al.iterator();
while(it.hasNext())
{
if(!al2.contains(it.next()))
{
al2.add(it.next());
}
}
return al2;
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
将自定义对象作为元素存到ArrayList集合中,并去除重复元素。比如:存人对象。同姓名同年龄,视为同一个人。为重复元素。
思路:
1,对人描述,将数据封装进人对象。
2,定义容器,将人存入。
3,取出。
List集合判断元素是否相同,依据是元素的equals方法。
package days7;
import java.util.*;
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 class ArrayList2
{
public static void main(String[]args)
{
ArrayList al=new ArrayList();
al.add(new Person("Ben",15));
al.add(new Person("Ann",12));
al.add(new Person("Bob",14));
al.add(new Person("Sam",16));
Iterator it=al.iterator();
while(it.hasNext())
{
Object obj=it.next();
Person p=(Person)obj;
sop(p.getName()+"::"+p.getAge());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
HashSet
Set——是无序的,元素不可以重复(存入和取出顺序不一定一致)
Set集合的功能和Collection是一致的
练习代码:
package days7;
import java.util.*;
public class HashSet1
{
public static void main(String[]args)
{
HashSet hs=new HashSet();
hs.add("java01");
hs.add("java02");
hs.add("java03");
hs.add("java04");
Iterator it=hs.iterator();
while(it.hasNext())
{
sop(it.next());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
HashSet是如何保证程序唯一性的
是通过元素两个方法,hashcode和equals来完成
如果元素的Hashcode值相同,才会判断equals是否为true
如果Hashcode值不同,不会调用equals
需求:往hashSet集合中存入自定对象
姓名和年龄相同为同一个人,重复元素。
package days7;
import java.util.*;
class Person2
{
private String name;
private int age;
Person2(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;
Person2 p=(Person2)obj;
return this.name.equals(p.name) && this.age == p.age;
}
}
public class HashSet2
{
public static void main(String[]args)
{
HashSet hs=new HashSet();
hs.add(new Person2("Ben",15));
hs.add(new Person2("Ann",20));
hs.add(new Person2("Tom",25));
hs.add(new Person2("Sam",30));
Iterator it=hs.iterator();
while(it.hasNext())
{
Person2 p=(Person2)it.next();
sop(p.getName()+"::"+p.getAge());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
HashSet判断和删除依据
注意:对于判断元素是否存在及删除等操作,依赖的方法是元素的Hashcode和equals方法
Set:无序,不可以重复元素
HashSet:数据结构是哈希表,线程是非同步的,保证元素唯一性的原理是:hashCode是否相同,如果相同还会继续判断equals方法,是否为true
TreeSet:可以对Set集合中的元素进行排序
练习代码:
package days8;
import java.util.*;
public class TreeSet1
{
public static void main(String[]args)
{
TreeSet tr=new TreeSet();
tr.add("cba");
tr.add("abc");
tr.add("aaa");
tr.add("bca");
Iterator it=tr.iterator();
while(it.hasNext())
{
sop(it.next());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
package days8;
import java.util.*;
class Person implements Comparable
{
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 int compareTo(Object obj) {
if(!(obj instanceof Person))
throw new RuntimeException("不是学生对象");
Person s = (Person)obj;
System.out.println(this.name+"....compareto....."+s.name);
if(this.age>s.age)
return 1;
if(this.age==s.age)
{
return this.name.compareTo(s.name);
}
return -1;
}
}
public class TreeSet2
{
public static void main(String[]args)
{
TreeSet al=new TreeSet();
al.add(new Person("Ben",15));
al.add(new Person("Ann",12));
al.add(new Person("Bob",14));
al.add(new Person("Sam",16));
Iterator it=al.iterator();
while(it.hasNext())
{
Object obj=it.next();
Person p=(Person)obj;
sop(p.getName()+"::"+p.getAge());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
TreeSet:可以对Set集合中元素进行排序,底层数据结构是二叉树
保证元素唯一性依据:compareTo 方法 return 0
实现CompareTo方式排序
TreeSet的第二种排序方式:当元素自身不具备比较性时,或者具备的比较性不是所需要的
这时候需要让集合自身具备比较性,定义了比较器,将比较器作为参数,传递给TreeSet集合的构造函数,当两种排序都存在时,以比较器为主
练习代码:
package days8;
import java.util.*;
class Person2
{
private String name;
private int age;
Person2(String name,int age)
{
this.name=name;
this.age=age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
class Mycompare implements Comparator
{
public int compare(Object o1, Object o2) {
Person2 p1=(Person2)o1;
Person2 p2=(Person2)o2;
int num=p1.getName().compareTo(p2.getName());
if(num==0)
{
if(p1.getAge()>p2.getAge())
return 1;
if(p1.getAge()==p2.getAge())
return 0;
else
return -1;
}
return num;
}
}
public class TreeSet3
{
public static void main(String[]args)
{
TreeSet al=new TreeSet(new Mycompare());
al.add(new Person2("Ben",15));
al.add(new Person2("Ann",12));
al.add(new Person2("Bob",14));
al.add(new Person2("Bob",9));
al.add(new Person2("Sam",16));
Iterator it=al.iterator();
while(it.hasNext())
{
Object obj=it.next();
Person2 p=(Person2)obj;
sop(p.getName()+"::"+p.getAge());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
需求:按照字符串长度排序
package days8;
import java.util.*;
class Treetest
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet(new Len());
ts.add("abcd");
ts.add("cc");
ts.add("cba");
ts.add("aaa");
ts.add("z");
ts.add("hahaha");
Iterator it = ts.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
class Len implements Comparator
{
public int compare(Object o1, Object o2)
{
String str1=(String)o1;
String str2=(String)o2;
int num=new Integer(str1.length()).compareTo(new Integer(str2.length()));
if(num==0)
return str1.compareTo(str2);
return num;
}
}
18、泛型限定
概述:
JDK1.4版本以后出现的新特性,用于解决安全问题是一个安全机制
好处:
1、将运行时期出现的问题ClassCastException,转移到了编译时期,方便程序解决问题,让运行期间问题减少,安全
2、避免了强制转换的麻烦
练习代码:
import java.util.*;
public class Gener1
{
public static void main(String[]args)
{
ArrayList<String> al=new ArrayList<String>();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
Iterator<String>it=al.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
泛型格式
通过< >来定义要操作的引用数据类型
在使用java提供的对象时,什么时候使用泛型?
通常在集合框架中很常见。只要见到< >就见到泛型,其实< >就是用来接收类型的。当使用集合时,将集合中要存储的数据类型作为参数传递到< >中即可
import java.util.*;
public class Gener2
{
public static void main(String[]args)
{
TreeSet<String> tr=new TreeSet<String>(new lenc());
tr.add("abcd");
tr.add("cc");
tr.add("cba");
tr.add("aaa");
tr.add("z");
tr.add("hehhe");
Iterator<String> it=tr.iterator();
while(it.hasNext())
{
String s=it.next();
System.out.println(s);
}
}
}
class lenc implements Comparator<String>
{
public int compare(String o1, String o2) {
int num=new Integer(o1.length()).compareTo(new Integer(o2.length()));
if(num==0)
return o1.compareTo(o2);
return num;
}
}
什么时候定义泛型类
当类中要操作的引用数据不确定时,早期定义Object类来完成扩展,现在定义泛型类来完成扩展
练习代码:
package days8;
import java.util.*;
class Utils<QQ>
{
private QQ q;
public void setObject(QQ q)
{
this.q = q;
}
public QQ getObject()
{
return q;
}
public void setObject(Student student) {
// TODO Auto-generated method stub
}
}
class Worker
{
}
class Student
{
}
class Gener3
{
public static void main(String[] args)
{
Utils<Worker> u = new Utils<Worker>();
u.setObject(new Student());
Worker w = u.getObject();;
/*
Tool t = new Tool();
t.setObject(new Student());
Worker w = (Worker)t.getObject();
*/
}
}
泛型方法
泛型类定义的泛型,在整个类中都有效。如果被方法使用,那么泛型类的对象明确要操作具体类型后,所有要操作的类型就已经固定了。
为了让不同方法可以操作不同的类型,而且类型还不确定,那么可以将泛型定义在方法上
特殊之处:
静态方法不可以访问类上定义的泛型。
如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。
练习代码:
package days8;
class Demo
{
public <T> void show(T t)
{
System.out.println("show"+t);
}
public <Q> void print(Q q)
{
System.out.println("print"+q);
}
}
public class Gener4
{
public static void main(String[]args)
{
Demo d=new Demo();
d.show("haha");
d.show(new Integer(4));
d.print("heihei");
}
}
泛型接口
泛型定义在接口上
package days8;
interface Inter<T>
{
<T> void show(T t);
}
class Imp<T> implements Inter<T>
{
public<T> void show(T t)
{
System.out.println("show:"+t);
}
}
public class Gener5
{
public static void main(String[]args)
{
Imp<Integer> i=new Imp<Integer>();
i.show(4);
Imp<String> j=new Imp<String>();
j.show("abc");
}
}
泛型限定
? 通配符。也可以理解为占位符。
泛型的限定;
? extends E: 可以接收E类型或者E的子类型。上限。
? super E: 可以接收E类型或者E的父类型。下限
package days8;
import java.util.*;
class Persons
{
private String name;
Persons(String name)
{
this.name=name;
}
public String getName()
{
return name;
}
}
class Students extends Persons
{
Students(String name)
{
super(name);
}
}
class Comp implements Comparator<Person>
{
public int compare(Person o1, Person o2)
{
return (o1.getName()).compareTo(o2.getName());
}
}
public class Gener6
{
public static void main(String[]args)
{
ArrayList<Persons>al =new ArrayList<Persons>();
al.add(new Persons("abc01"));
al.add(new Persons("abc02"));
al.add(new Persons("abc03"));
al.add(new Persons("abc04"));
print(al);
System.out.println();
ArrayList<Students>al2=new ArrayList<Students>();
al2.add(new Students("def01"));
al2.add(new Students("def02"));
al2.add(new Students("def03"));
al2.add(new Students("def04"));
print(al2);
System.out.println();
}
public static void print(Collection<? extends Persons>al)
{
Iterator<? extends Persons> it=al.iterator();
while(it.hasNext())
{
System.out.print(" "+it.next().getName());
}
}
}
package days8;
import java.util.*;
class People
{
private String name;
People(String name)
{
this.name=name;
}
public String getName()
{
return name;
}
}
class Workers extends People
{
private int age;
Workers(String name,int age)
{
super(name);
this.age=age;
}
public int getAge()
{
return age;
}
}
class Mycompare3 implements Comparator<People>
{
public int compare(People p1, People p2)
{
return p1.getName().compareTo(p2.getName());
}
}
class Mycompare4 implements Comparator<Workers>
{
public int compare(Workers p1, Workers p2)
{
return p1.getName().compareTo(p2.getName());
}
}
public class Gener7
{
public static void main(String[]args)
{
TreeSet<People> tr=new TreeSet<People>(new Mycompare3());
tr.add(new People("e"));
tr.add(new People("de"));
tr.add(new People("cde"));
tr.add(new People("bcde"));
prints(tr);
TreeSet<Workers> wk=new TreeSet<Workers>(new Mycompare4());
wk.add(new Workers("ab",10));
wk.add(new Workers("bc",8));
wk.add(new Workers("cd",6));
wk.add(new Workers("ef",4));
prints(wk);
}
public static void prints(Collection<? extends People> al)
{
Iterator<? extends People> it=al.iterator();
while(it.hasNext())
{
System.out.print(it.next().getName()+" ");
19、Map
Map集合:该集合存储键值对。一对一对往里存。而且要保证键的唯一性。
1,添加。
put(K key, V value)
putAll(Map<? extends K,? extends V> m)
2,删除。
clear()
remove(Object key)
3,判断。
containsValue(Object value)
containsKey(Object key)
isEmpty()
4,获取。
get(Object key)
size()
values()
entrySet()
keySet()
Map
|--Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。jdk1.0.效率低。
|--HashMap:底层是哈希表数据结构,允许使用 null 值和 null 键,该集合是不同步的。将hashtable替代,jdk1.2.效率高。
|--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。
和Set很像。
其实,Set底层就是使用了Map集合。
练习代码:
package days9;
import java.util.*;
public class Map1
{
public static void main(String[]args)
{
Map<String,String>map=new HashMap<String,String>();
map.put("01", "a");
map.put("02", "b");
map.put("03", "c");
map.put("04", "d");
sop(map);
sop(map.remove("01"));
sop(map);
sop(map.get("05"));
sop(map);
Collection coll=map.values();
sop(coll);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
Map集合的两种取出方式
1,Set<k> keySet:将map中所有的键存入到Set集合。因为set具备迭代器。所有可以迭代方式取出所有的键,在根据get方法。获取每一个键对应的值。
Map集合的取出原理:将map集合转成set集合。在通过迭代器取出。
2,Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.EntryEntry其实就是Map中的一个static内部接口。
为什么要定义在内部呢?
因为只有有了Map集合,有了键值对,才会有键值的映射关系。关系属于Map集合中的一个内部事物。而且该事物在直接访问Map集合中的元素。
package days9;
import java.util.*;
public class Map2
{
public static void main(String[]args)
{
Map<String,String>map=new HashMap<String,String>();
map.put("01", "a");
map.put("02", "b");
map.put("03", "c");
map.put("04", "d");
Set<String>kt=map.keySet();
Iterator it=kt.iterator();
while(it.hasNext())
{
String key=(String)it.next();
String value=map.get(key);
System.out.println(key+"::"+value);
}
}
}
package days9;
import java.util.*;
import java.util.Map.*;
public class Map3
{
public static void main(String[]args)
{
Map<String,String>map=new HashMap<String,String>();
map.put("01", "a");
map.put("02","b");
map.put("03","c");
map.put("04","d");
Set<Map.Entry<String, String>>entry=map.entrySet();
Iterator it=entry.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
Iterator it2=entry.iterator();
while(it2.hasNext())
{
Map.Entry<String, String> m=(Entry<String, String>) it2.next();
String key=m.getKey();
String value=m.getValue();
System.out.println(key+"::"+value);
}
}
}
Map.Entry 其实Entry也是一个接口,它是Map接口中的一个内部接口。
interface Map
{
public static interface Entry
{
public abstract Object getKey();
public abstract Object getValue();
}
}
class HashMap implements Map
{
class Hahs implements Map.Entry
{
public Object getKey(){}
public Object getValue(){}
}
}
每一个学生都有对应的归属地。
学生Student,地址String。
学生属性:姓名,年龄。
注意:姓名和年龄相同的视为同一个学生。
保证学生的唯一性。
思路:
1,描述学生。
2,定义map容器。将学生作为键,地址作为值。存入。
3,获取map集合中的元素。
package days9;
import java.util.*;
class Student
{
private String name;
private int age;
Student(String name,int age)
{
this.name=name;
this.age=age;
}
public int getAge()
{
return age;
}
public String getName()
{
return name;
}
}
public class MapTest1
{
public static void main(String[]args)
{
Map<Student,String> hs=new HashMap<Student,String>();
hs.put(new Student("zhangsan",15), "Beijing");
hs.put(new Student("lisi",13), "Henan");
hs.put(new Student("wangwu",12), "Hunan");
hs.put(new Student("zhangsan",11), "Shanghai");
Set<Map.Entry<Student, String>> entry=hs.entrySet();
Iterator<Map.Entry<Student, String>> it=entry.iterator();
while(it.hasNext())
{
Map.Entry<Student, String> m=it.next();
Student k=m.getKey();
String v=m.getValue();
sop(k.getName());
sop(k.getAge());
sop(m.getValue());
System.out.println();
}
System.out.println();
Set<Student> key=hs.keySet();
Iterator<Student>it2=key.iterator();
while(it2.hasNext())
{
Student stu=it2.next();
String add=hs.get(stu);
sop(stu.getName());
sop(stu.getAge());
sop(add);
System.out.println();
}
}
public static void sop(Object obj)
{
System.out.print(" "+obj);
}
}
需求:对学生对象的年龄进行升序排序。
因为数据是以键值对形式存在的。
所以要使用可以排序的Map集合。TreeMap。
package days9;
import java.util.*;
class Students implements Comparable<Students>
{
private String name;
private int age;
Students(String name,int age)
{
this.name=name;
this.age=age;
}
public int getAge()
{
return age;
}
public String getName()
{
return name;
}
public int compareTo(Students s)
{
int num=new String(this.name).compareTo(new String(s.name));
if(num==0)
return new Integer(this.age).compareTo(s.age);
return num;
}
}
public class MapTest2
{
public static void main(String[]args)
{
Map<Students,String> hs=new TreeMap<Students,String>();
hs.put(new Students("zhangsan",15), "Beijing");
hs.put(new Students("lisi",13), "Henan");
hs.put(new Students("wangwu",12), "Hunan");
hs.put(new Students("zhangsan",11), "Shanghai");
Set<Map.Entry<Students, String>> entry=hs.entrySet();
Iterator<Map.Entry<Students, String>> it=entry.iterator();
while(it.hasNext())
{
Map.Entry<Students, String> m=it.next();
Students k=m.getKey();
String v=m.getValue();
sop(k.getName());
sop(k.getAge());
sop(m.getValue());
System.out.println();
}
System.out.println();
Set<Students> key=hs.keySet();
Iterator<Students>it2=key.iterator();
while(it2.hasNext())
{
Students stu=it2.next();
String add=hs.get(stu);
sop(stu.getName());
sop(stu.getAge());
sop(add);
System.out.println();
}
}
public static void sop(Object obj)
{
System.out.print(" "+obj);
}
}
"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。
希望打印结果:a(1)c(2).....
通过结果发现,每一个字母都有对应的次数。
说明字母和次数之间都有映射关系。
当发现有映射关系时,可以选择map集合。
因为map集合中存放就是映射关系。
什么使用map集合呢?
当数据之间存在这映射关系时,就要先想map集合。
思路:
1,将字符串转换成字符数组。因为要对每一个字母进行操作。
2,定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。
3,遍历字符数组。
将每一个字母作为键去查map集合。
如果返回null,将该字母和1存入到map集合中。
如果返回不是null,说明该字母在map集合已经存在并有对应次数。
那么就获取该次数并进行自增。,然后将该字母和自增后的次数存入到map集合中。覆盖调用原理键所对应的值。
4,将map集合中的数据变成指定的字符串形式返回。
package days9;
import java.util.*;
import java.util.Map.*;
public class MapTest3
{
public static void main(String[]args)
{
String str="ak+abAf1c,dCkaAbc-defa";
System.out.println(Charcount(str));
}
public static String Charcount(String str)
{
TreeMap<Character,Integer> tr=new TreeMap<Character,Integer>();
char[]ch=str.toCharArray();
Integer value=null;
for(int x=0;x<ch.length;x++)
{
if(!(ch[x]>='a' && ch[x]<='z' || ch[x]>='A' && ch[x]<='Z'))
continue;
value=tr.get(ch[x]);
if(value==null)
value=1;
else
{
value++;
}
tr.put(ch[x], value);
}
//System.out.print(" "+tr);
Set<Map.Entry<Character, Integer>>entry=tr.entrySet();
Iterator<Map.Entry<Character, Integer>>it=entry.iterator();
StringBuilder st=new StringBuilder();
while(it.hasNext())
{
Map.Entry<Character, Integer>m=it.next();
st.append(m.getKey()+"(");
st.append(m.getValue()+"),");
}
String str2=st.toString();
return str2;
}
}
20、集合框架的工具类——Collections
Collections:集合框架的工具类。里面定义的都是静态方法。
Collections和Collection有什么区别?
Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。
它有两个常用的子接口,
List:对元素都有定义索引。有序的。可以重复元素。
Set:不可以重复元素。无序。
Collections是集合框架中的一个工具类。该类中的方法都是静态的
提供的方法中有可以对list集合进行排序,二分查找等方法。
通常常用的集合都是线程不安全的。因为要提高效率。
如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。
Collections-sort
package days10;
import java.util.*;
class Strlen implements Comparator<String>
{
public int compare(String s1, String s2)
{
int num=new Integer(s1.length()).compareTo(new Integer(s2.length()));
return num;
}
}
public class Collections1
{
public static void main(String[]args)
{
List<String> list=new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("z");
list.add("kkkkk");
list.add("qq");
sop(list);
Collections.sort(list);
sop(list);
Collections.sort(list, new Strlen());
sop(list);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
Collections-max
package days10;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class Strlens implements Comparator<String>
{
public int compare(String s1, String s2)
{
int num=new Integer(s1.length()).compareTo(new Integer(s2.length()));
return num;
}
}
public class Collections2
{
public static void main(String[]args)
{
List<String> list=new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("z");
list.add("kkkkk");
list.add("qq");
sop(list);
Collections.sort(list);
sop(list);
String max=Collections.max(list);
sop("max="+max);
String min=Collections.min(list);
sop("min="+min);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
Collections-BinarySearch
package days10;
import java.util.*;
class Strlen3 implements Comparator<String>
{
public int compare(String s1, String s2)
{
int num=s1.compareTo(s2);
return num;
}
}
public class Collections3
{
public static void main(String[]args)
{
List<String> list=new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("z");
list.add("kkkkk");
list.add("qq");
sop(list);
Collections.sort(list);
sop(list);
Collections.sort(list, new Strlen3());
sop(list);
int index=Collections.binarySearch(list, "qq" );
sop("index="+index);
sop("index="+halfSearch(list,"qq"));
}
public static void sop(Object obj)
{
System.out.println(obj);
}
public static int halfSearch(List<String>list,String key)
{
int max,min,mid;
max=list.size()-1;
min=0;
while(min<max)
{
mid=(max+min)/2;
String str=list.get(mid);
int num=str.compareTo(key);
if(num>0)
max=mid-1;
if(num<0)
min=mid+1;
else
return mid;
}
return 0;
}
}
Collections—替换和反转
Fill方法可以将list集合中所有元素替换成指定元素
ReplaceAll将list集合中部分元素替换成指定元素
package days10;
import java.util.*;
public class Collections4
{
public static void main(String[]args)
{
List<String> list=new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("z");
list.add("kkkkk");
list.add("qq");
sop(list);
Collections.sort(list);
sop(list);
Collections.sort(list, new Strlen3());
sop(list);
Collections.replaceAll(list, "qq", "st");
sop(list);
Collections.fill(list, "pp");
sop(list);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
Collections-reversOrder
package days10;
import java.util.*;
class Strlen4 implements Comparator<String>
{
public int compare(String s1, String s2)
{
return s2.compareTo(s1);
}
}
public class Collections5
{
public static void main(String[]args)
{
TreeSet<String> tr=new TreeSet<String>(Collections.reverseOrder());
tr.add("abcd");
tr.add("aaa");
tr.add("z");
tr.add("kkkkk");
tr.add("qq");
sop(tr);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
package days10;
import java.util.*;
public class Collections6
{
public static void main(String[]args)
{
List<String> list=new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("z");
list.add("kkkkk");
list.add("qq");
sop(list);
Collections.sort(list);
sop(list);
Collections.swap(list, 1, 2);
sop(list);
Collections.shuffle(list);
sop(list);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
21、Arrarys
概述
用于操作数组的工具类,里面都是静态方法
asList:将数组变成List集合
把数组变成集合的好处:
可以用集合的思想和方法来操作数组中的元素
注意:将数组变成集合,不可以使用集合的增删方法,因为数组的长度是固定的
如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转换成集合中的元素
如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在
package days10;
import java.util.*;
public class Array1
{
public static void main(String[]args)
{
int[]arr={2,4,5};
sop(Arrays.toString(arr));
String[]str={"abc","cc","kkkk"};
List<String>list=Arrays.asList(str);
sop(list);
sop(list.contains("cc"));
Integer[]nums={2,4,5};
List<Integer> list2=Arrays.asList(nums);
sop(list2);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
集合变数组
Collection接口中的toArray方法。
1,指定类型的数组到底要定义多长呢?
当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组。长度为集合的size。
当指定类型的数组长度大于了集合的size,就不会新创建了数组。而是使用传递进来的数组。
所以创建一个刚刚好的数组最优。
2,为什么要将集合变数组?
为了限定对元素的操作。不需要进行增删了。
package days10;
import java.util.*;
public class Array2
{
public static void main(String[]args)
{
ArrayList<String>al=new ArrayList<String>();
al.add("abc1");
al.add("abc2");
al.add("abc3");
String []arr=al.toArray(new String[1]);
sop(arr);
sop(Arrays.toString(arr));
sop(al.toString());
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
}
}
}