集合
Collection 集合接口:
主要方法:
1、boolean add(Object o)添加对象到集合
2、boolean remove(Object o)删除指定的对象
3、int size()返回当前集合中元素的数量
4、boolean contains(Object o)查找集合中是否有指定的对象
5、boolean isEmpty()判断集合是否为空
6、Iterator iterator()返回一个迭代器
7、boolean containsAll(Collection c)查找集合中是否有集合c中的元素
8、boolean addAll(Collection c)将集合c中所有的元素添加给该集合
9、void clear()删除集合中所有元素
10、void removeAll(Collection c)从集合中删除c集合中也有的元素
11、void retainAll(Collection c)从集合中删除集合c中不包含的元素
注意:容器类对象在调用remove,contains等方法时需要比较对象是否相等,这会涉及到对象类型的equals方法和hashCode方法;对于自定义类型,需要重写equals和hashCode方法以实现自定义对象的相等规则。相等的对象应该具有相等的hashcodes。
增加Name类的equals和hashCode方法如下:
public class Name {
private String firstName,lastName;
public Name(String firstName,String lastName){
this.firstName = firstName;
this.lastName = lastName;
}
public String toString() {
return firstName+" "+lastName;
}
public boolean equals(Object obj) {
if(obj instanceof Name) {
Name name = (Name)obj;
return (firstName.equals(name.firstName)&&lastName.equals(name.lastName));
}
return super.equals(obj);
}
public int nashCode() {
return firstName.hashCode();
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
import java.util.*;
public class Test {
public static void main(String[] args) {
Collection c = new LinkedList();
c.add(new Name("f1","l1"));
c.add(new Name("f2","l2"));
c.add(new Name("f3","l3"));
System.out.println(c.contains(new Name("f2","l2")));
c.remove(new Name("f1","l1"));
System.out.println(c);
}
}
运行结果为:true
[f2 l2, f3 l3]
Iterator接口:
所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象。
Iterator对象称作迭代器,用以方便的实现对容器内的元素的遍历操作。
Iterator接口定义如下方法:
1、boolean hasNext();//判断游标右边是否有元素
2、Object next();//返回游标右边的元素并将游标移动到下一位子
3、void remove();//删除游标左边的元素在执行完next之后该操作只能执行一次
eg:
import java.util.*;
public class Test {
public static void main(String[] args) {
Collection c = new LinkedList();
c.add(new Name("f1","l1"));
c.add(new Name("f2","l2"));
c.add(new Name("f3","l3"));
Iterator i = c.iterator();
while (i.hasNext()) {
Name n = (Name)i.next();
//next()返回值为Object类型,需要转换为相应类型
System.out.print(n.getFirstName()+" ");
}
}
}
//运行结果为:f1 f2 f3
Iterator对象的remove方法是在迭代过程中删除元素唯一安全的方法
eg:
import java.util.*;
public class Test {
public static void main(String[] args) {
Collection c = new LinkedList();
c.add(new Name("f11111","l11111"));
c.add(new Name("f2","l2"));
c.add(new Name("f33333","l33333"));
for(Iterator i = c.iterator();i.hasNext();) {
Name n = (Name)i.next();
if(n.getFirstName().length()<3){
i.remove();
//换成c.remove(name);会产生例外,Iterator遍历过程中执行了锁定,把当前元素锁住,只有自己能动,所以要调用iterator的remove
}
}
System.out.println(c);
}
}
//运行结果为:[f11111 l11111, f33333 l33333]
扩展:增强型for循环
缺点:不能方便的访问下标值,不能方便的删除元素,只能简单的遍历。
eg:
import java.util.*;
public class Test {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add(new String("f11111"));
c.add(new String("f22222"));
c.add(new String("f33333"));
for(Object o:c){
System.out.println(o);
}
int[] arr = {1,2,3,4,5};
for(int i:arr){
System.out.println(i);
}
}
}
//输出结果:f11111 f22222 f33333 1 2 3 4 5
Set接口:
Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。Set接口的容器类的元素是没有顺序的,而且不可以重复(重复的元素不会被加入),主要有HashSet,TreeSet等。
eg:
import java.util.*;
public class Test {
public static void main(String[] args) {
Set s1 = new HashSet();
Set s2 = new HashSet();
s1.add("a");s1.add("b");s1.add("c");
s2.add("d");s2.add("a");s2.add("b");
Set sn = new HashSet(s1);
sn.retainAll(s2);//求交集
Set su = new HashSet(s1);
su.addAll(s2);//求并集
System.out.println(sn);
System.out.println(su);
}
}
//结果为:[a, b] [a, b, c, d]
List接口:
List是有序的Collection,可以随意改变大小,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,List允许有相同的元素。
实现List接口的常用类有LinkedList(和链表很像),ArrayList,Vector和Stack。
主要方法:
1、void add(int index,Object element)在指定位置上添加一个对象
2、boolean addAll(int index,Collection c)将集合c的元素添加到指定的位置
3、Object get(int index)返回List中指定位置的元素
4、int indexOf(Object o)返回第一个出现元素o的位置.
5、Object removeint(int index)删除指定位置的元素
6、Object set(int index,Object element)用元素element取代位置index上的元素,返回被取代的元素
import java.util.*;
public class Test {
public static void main(String[] args) {
List l1 = new LinkedList();
for(int i = 0 ; i <= 5; i++) {
l1.add("a"+i);
}
System.out.println(l1);
l1.add(3,"a100");
System.out.println(l1);
l1.set(6,"a200");
System.out.println(l1);
System.out.println((String)l1.get(2));
System.out.println(l1.indexOf("a3"));
l1.remove(1);
System.out.println(l1);
}
}
//输出结果为:[a0, a1, a2, a3, a4, a5] [a0, a1, a2, a100, a3, a4, a5]
// [a0, a1, a2, a100, a3, a4, a200] a2 4 [a0, a2, a100, a3, a4, a200]
List常用算法:
1、void sort(List) //对List容器内的元素排序
2、void shufflr(List) //对List容器内的对象进行随机排序
3、void reverse(List) //对List容器内的对象进行逆序排序
4、void fill (List,Object) //用一个特定的对象重写整个List容器
5、void copy(List dest,List src) //将src容器内容拷贝到dest容器
5、int binarySearch(List,Object) //对于顺序的List容器,采用折半查找的方法查找特定对象
import java.util.*;
public class Test {
public static void main(String[] args) {
List l1 = new LinkedList();
List l2 = new LinkedList();
for(int i = 0 ; i <= 9; i++){
l1.add("a"+i);
}
System.out.println(l1);
Collections.shuffle(l1);
System.out.println(l1);
Collections.reverse(l1);
System.out.println(l1);
Collections.sort(l1);
System.out.println(l1);
System.out.println(Collections.binarySearch(l1,"a5"));
}
}
//输出结果为 :[a0, a1, a2, a3, a4, a5, a6, a7, a8, a9]
// [a5, a6, a3, a0, a2, a7, a1, a8, a4, a9]
// [a9, a4, a8, a1, a7, a2, a0, a3, a6, a5]
// [a0, a1, a2, a3, a4, a5, a6, a7, a8, a9]
// 5
Comparable接口:
所有可以“排序”的类都实现了java.lang.Comparable接口,该接口只有一种方法public int compareTo(Object obj);该方法返回0表示this==obj;返回正数表示this>obj;返回负数表示this<obj。实现了Conparable接口的类通过实现compareTo方法从而确定该类对象的排序方式。
改写Name类让其实现Comparable接口,其compareTo方法定义为:
public class Name implements Comparable {
.....................
public int compareTo(Object o) {
Name n = (Name)o;
int lastCmp = lastName.compareTo(n.lastName);
return (lastCmp!=0 ? lastCmp : firstName.compareTo(n.firstName));//lastname不同就输出lastCmp;不然就继续比较firstname
}
.....................
}
import java.util.*;
public class Test {
public static void main(String[] args) {
List l1 = new LinkedList();
l1.add(new Name("Karl","M"));
l1.add(new Name("Steven","Lee"));
l1.add(new Name("John","O"));
l1.add(new Name("Tom","M"));
System.out.println(l1);
Collections.sort(l1);
System.out.println(l1);
}
}
//输出结果为:[Karl M, Steven Lee, John O, Tom M]
// [Steven Lee, Karl M, Tom M, John O]
如何选择数据结构:
衡量标准:读的效率和改的效率
Array —— 读快改慢
Linked —— 改快读慢
Hash —— 两者之间
Map接口:
Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个value。Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。实现类有HashMap、TreeMap等。
主要方法:
1、boolean equals(Object o)比较对象
2、boolean remove(Object o)删除一个对象
3、Object put(Object key,Object value)添加key和value
4、Object get(Object key)
5、boolean containsKey\Value(Object Key)
6、void clear()
7、void putAll(Map t)
8、int size()
eg:
import java.util.*;
public class Test {
public static void main(String[] args) {
Map m1 = new HashMap();
Map m2 = new TreeMap();
m1.put("one",1);
m1.put("two",2);
m1.put("three",3);
m2.put("A",1);
m2.put("B",2);
System.out.println(m1.size());
System.out.println(m1.containsKey("one"));
System.out.println(m2.containsValue(1));
if(m1.containsKey("two")) {
int i = ((Integer)m1.get("two")).intValue();
System.out.println(i);
}
Map m3 = new HashMap(m1);
m3.putAll(m2);
System.out.println(m3);
}
}
//结果为3
// true
// true
// 2
// {A=1, B=2, two=2, three=3, one=1}
Auto-boxing/unboxing:
自动打包/解包。
eg:
int i = ((Integer)m1.get(“two”)).intValue();可以写成int i = (Integer)m1.get(“two”);
泛型:增强了程序的可读性和稳定性
用于规定指定类型
eg1:
import java.util.*;
public class Test {
public static void main(String[] args) {
List<String> l = new ArrayList<String>();//里面只能装String类型
l.add("aaa");l.add("bbb");l.add("ccc");
for(int i = 0;i<l.size();i++) {
String s = l.get(i);
System.out.println(s);
}
Collection<String> c2 = new HashSet<String>();
c2.add("aaa");c2.add("bbb");c2.add("ccc");
for(Iterator<String> it = c2.iterator();it.hasNext();) {
String s = it.next();
System.out.println(s);
}
}
}
//输出结果为:aaa bbb ccc aaa ccc bbb
eg2:
class MyName implements Comparable<MyName> {
int age;
public int CompareTo(MyName mn) {//不用强制转换了
if(this.age > mn.age) return 1;
else if(this.age < mn.age) return -1;
else return 0;
}
}