允许重复的子接口List(重点,80%)
List接口是Collection之中最为常用的子接口,也是大家在开发过程之中主要使用的接口,但是List在Collection基础上做了大量的功能扩充,
而主要扩充的方法有如下几个
方法名称 | 类型 | 描述 |
public E get(int index) | 普通 | 取得指定索引位置上的对象 |
public E set(int index,E element) | 普通 | 修改指定索引位置上的对象 |
public ListIterator<E> listIterator | 普通 | 为ListIterator接口实例化 |
那么接口完成后如果要想使用接口那么一定需要子类,而常用的两个子类:ArrayList,Vector
新的子类:ArrayList(大多数)
ArrayList实在JDK1.2之后引入的,也是在List接口使用过程之中最为常用的一个子类
范例:使用ArrayList
package classJI;
import java.util.ArrayList;
import java.util.List;
//ArrayList
public class classjia {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> all=new ArrayList<String>();
all.add("HELLO");
all.add("HELLO");//重复
all.add("WORLD");
System.out.println(all);
}
}
但是在很多时候可以采用熏坏的方式输出,因为在List子接口里面扩充了一个方法get()方法
范例:循环输出List集合
package classJI;
import java.util.ArrayList;
import java.util.List;
//ArrayList
public class classjia {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> all=new ArrayList<String>();
all.add("HELLO");
all.add("HELLO");//重复
all.add("WORLD");
for(int x=0;x<all.size();x++) {
System.out.println(all.get(x));
}
}
}
验证其它方法
package classJI;
import java.util.ArrayList;
import java.util.List;
public class classjib {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> all=new ArrayList<String>();
System.out.println(all.isEmpty());
all.add("HELLO");
all.add("HELLO");//重复
all.add("WORLD");
System.out.println(all.isEmpty());
all.set(0,"hello");//此方法也是List扩充
all.remove("WORLD");
System.out.println(all);
}
}
但是以上的程序之中发现操作的数据类型都是String,那么String类是一个比较完善的类,那么下面使用一个
自己自定义的类进行操作
范例:保存自定义类对象
package classJI;
import java.util.ArrayList;
import java.util.List;
class Person{
private String name;
private int age;
public Person(String name,int age) {
this.name=name;
this.age=age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
public class classjic {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Person> all=new ArrayList<Person>();
all.add(new Person("张三",20));
all.add(new Person("李四",21));
all.add(new Person("王五",19));
all.remove(new Person("王五",19));//删除
System.out.println(all.contains(new Person("李四",21)));
System.out.println(all);
}
}
那么在之前使用的链表操作,在List接口上可以方便的使用,使用的规则与之前完全一样,可是List采用
的逻辑更加合理,所以不会使用自定义链表,都会使用List接口操作
旧的子类:Vector(少数)
Vector是从JDK1.0的时候引入的操作类,同时在JDK1.2之后为了让其可以继续使用,于是Vector类多实现
了一个List接口,使用List接口下有两个常用的子类:ArrayList,Vector
既然Vector也是List接口大的子类,所以在使用上,不管使用ArrayList还是Vector不会有任何的区别
范例:验证Vector
package classJI;
import java.util.ArrayList;
import java.util.List;
//Vector
public class classjia {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> all=new Vector<String>();
all.add("HELLO");
all.add("HELLO");//重复
all.add("WORLD");
System.out.println(all);
}
}
面试题:请解释ArrayList和Vector区别
ArrayList
Vector
1.推出时间
JDK1.2
JDK1.0
2.性能
采用异步处理方式,性能较高
采用同步处理,性能较低
3.安全
数据安全性差
数据安全性高
4.输出
Iterator,ListIterator,foreach
Iterator,ListIterator,Enumeration,foreach
考虑到日后的开发异步开发居多,所以以ArrayList类为主
不允许重复的子接口:Set
Set之中保存的元素是不能够有重复,但是Set接口并不像List接口那样对Collection进行了方法的扩充,而是
完整继承了Collection接口的所有方法,那么也意味着,在之前使用get()方法就无法使用了
Set子接口之中重要使用两个常用的子类:HashSet,TreeSet
散列存放的子类:HashSet(多数)
Hash是一种散列算法,指的保存数据没有序列
package classJI;
import java.util.HashSet;
import java.util.Set;
public class CHashSet {
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<String> all=new HashSet<String>();
all.add("HELLO");
all.add("HELLO");//重复
all.add("WORLD");
all.add("笑笑");
all.add("哭哭");
System.out.println(all);
}
}
使用HashSet是不能够保存重复数据的,而且保存的数据没有任何的顺序
排序存放的子类:TreeSet(少数)
如果希望里面的数据排序,则可以使用TreeSet子类
package classJI;
import java.util.TreeSet;
import java.util.Set;
public class CHashSet {
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<String> all=new TreeSet<String>();
all.add("A");
all.add("D");
all.add("C");
all.add("B");
all.add("E");
System.out.println(all);
}
}
关于数据排序的说明
使用TreeSet可以实现集合中数据排序的保存,那么在之前使用的是String型数据,下面使用自定义类。但是
这个类如果要想正常的使用TreeSet保存,那么一定要在此类上实现java.lang.Comparable接口,以区分大小
但是在此时重写compareTo方法的时候必须注意到,所有的属性必须进行比较,否则就会出现部分属性内容
相同也会人为是同一对象的情况,造成数据的保存错误
范例:使用自定义类
package classJI;
import java.util.TreeSet;
import java.util.Set;
class Persona implements Comparable<Persona>{
private String name;
private int age;
public Persona(String name,int age) {
this.name=name;
this.age=age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Persona o) {
if(this.age>o.age) {
return -1;
}
else if(this.age<o.age) {
return 1;
}
return this.name.compareTo(o.name);
}
}
public class Classjie {
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<Persona> all=new TreeSet<Persona>();
all.add(new Persona("张三",20));
all.add(new Persona("李四",21));
all.add(new Persona("找刘",21));//年龄重复
all.add(new Persona("王五",19));
all.add(new Persona("王五",19));
System.out.println(all);
}
}
通过此时的程序也可以得出一个结论,TreeSet使用过程之中一定要使用Comparable接口,而且,TreeSet
集合里面是依靠Comparable接口的compareTo()方法返回的数据来区分是否为重复数据
关于重复数据的说明
Set子接口之中不允许保留重复数据,之前使用TreeSet子类虽然依靠了Comparable接口进行重复数据判断,
但是此判断的方式也只是针对于TreeSet这种排序结构起作用,而真正意义上的排序操作是不依靠接口的,而是
依靠Object类之中的两个方法:
取得对象的hash码:public int hashCode();
对象比较:public boolean equals(Object obj);
在判断对象是否重复的过程之中,其基本流程如下
首先使用要查询对象的 hashCode与集合之中的保存对象的每一个hashCode进行比较;
如果hashCode相同,则再使用 equals()方法进行内容的比较
范例:重复对象判断
package classJI;
import java.util.TreeSet;
import java.util.HashSet;
import java.util.Set;
class Persona implements Comparable<Persona>{
private String name;
private int age;
public Persona(String name,int age) {
this.name=name;
this.age=age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Persona other = (Persona) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
public class Classjie {
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<Persona> all=new HashSet<Persona>();
all.add(new Persona("张三",20));
all.add(new Persona("李四",21));
all.add(new Persona("找刘",21));//年龄重复
all.add(new Persona("王五",19));
all.add(new Persona("王五",19));
System.out.println(all);
}
}
任何情况如果是对象的重复判断,一定使用hashCode()和equals()。