Java集合(二)
一、set接口
- set接口是Collection的子接口,set接口没有提供额外的方法,但实现set接口的容器类中的元素是没有顺序的,而且不可以重复。
- set容器可以与数学中的“集合”的概念相对应
- Java api中所提供的set容器类有hashSet,treeSet等等。
示例如下:
public class SetTest {
public static void main(String[] args) {
Set set = new HashSet();
set.add("hello");
set.add("hi");
set.add(new Integer(103));
set.add("hi");//相同的元素不会被添加
System.out.println(set);
}
}
输出结果:
set集合是没有顺序的,而且两个对象不能equals,也就是说两个相等的元素只会添加一次。
二、List接口
- List接口是Collection的子接口,实现List接口的容器类中的元素是有顺序的,而且可以重复(如果元素之间equals的话,也可以正常添加)
- List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。
- J2SDK所提供的List容器类有ArrayList,LinkedList等。
- List常用的方法如下:
Object get(intt index);//把index位置上的元素返回,返回值为object
Object set(int index,Object element);//把index位置上的元素设置为element元素,返回旧的元素
void add(int index,Object element);//在index位置上添加一个element对象
Object remove(int index);//去除index位置上的元素
int indexOf(Object object);//object在容器里出现在第几个位置
int lastIndexOf(Object object);//object对象最后一次出现在容器的第几个位置
示例如下:
public class ListTest {
public static void main(String[] args) {
List<String> l1 = new LinkedList();
for(int i = 0;i <= 5;i++){
l1.add("a" + i);
}
System.out.println(l1);
l1.add(3,"a100");//在第三个位置上添加a100
System.out.println(l1);
l1.set(6,"a200");//把第六个位置上设置成a200
System.out.println(l1);
System.out.println(l1.get(2));
System.out.println(l1.indexOf("a3"));//a3出现在第几个位置
l1.remove(1);//移除第一个位置上的元素
System.out.println(l1);
}
输出结果:
三、List常用算法
java.util.Collections(这是Collections类,不要和collection接口混淆)提供上了一些静态方法,实现了基于List容器的一些常用算法。
void sort(list)//对list容器内的元素排序
void shuffle(list)//随机排序
void reverse(list)//逆序
void fill(list,object)//用一个特定的对象重写整个list容器
void copy(List dest,List src)//将src中的元素全部拷贝到dest中
int binarySearch(List,Object)//对于已经排好序(从大到小或者从小到大)的list容器,采用折半查找的方法查找特定对象
示例如下:
public class CollectionsTest {
public static void main(String[] args) {
List<String> 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"));//折半查找
}
}
输出结果:
四、Comparable接口(同类比较才具有意义)
所有可以“排序”的类都实现了java.lang.comparable接口,Comparable接口中只有一个方法public int compareTo(Object obj);
该方法:
返回0表示this(当前对象) == obj
返回正数表示this > obj
返回负数表示this < obj
实现了comparable接口的类通过实现compareTo方法来确定该类对象的排序方式。
示例如下:
public class Name implements Comparable{
private String firstName;
private String lastName;
public Name(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
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;
}
@Override
public String toString() {
return "Name{" +
"firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
'}';
}
/**
* 重写equals方法
*
* @param obj 对象
* @return 两个对象的比较结果,只有“我的名字”等于你传递给我的name对象的名字才返回true
*/
@Override
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);
}
/**
* 重写hashcode方法
*
* @return 暂时使用字符串的hashcode方法(也可以自己实现,但是稍微复杂,可以自己研究下)
*/
@Override
public int hashCode() {
return firstName.hashCode();
}
/**
* 按照姓名排列,首先比较姓,然后比较名字
* @param o
* @return
*/
@Override
public int compareTo(Object o) {
Name Name = (Name) o;
//使用String类的compareTo方法,也就是按照字母进行排序
int lastCmp = lastName.compareTo(Name.lastName);
return (lastCmp != 0 ? lastCmp :
firstName.compareTo(Name.firstName));
}
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);//排序然后输出,排序规则上面的compareTo方法确定的
System.out.println(l1);
}
输出结果:
[Name{firstName='Karl', lastName='M'}, Name{firstName='Steven', lastName='Lee'}, Name{firstName='John', lastName='o'}, Name{firstName='Tom', lastName='M'}]//第一次依次输出
[Name{firstName='Steven', lastName='Lee'}, Name{firstName='Karl', lastName='M'}, Name{firstName='Tom', lastName='M'}, Name{firstName='John', lastName='o'}]//按照姓氏首字母排列
五、如何选择数据结构
衡量标准:读的效率和改的效率
Array开头的集合读的快改的慢
Linked开头的集合改的快读的慢
Hash开头的集合读和写的速度在Array开头的集合和Linked开头集合的中间。