Java
集合
集合:
在java中,集合是指一个特殊的容器,其可以储存多个对象的引用,java的集合类可以储存数量不等的多个对象,还可用于保存具有映射关系的关联数组。
集合通常有三种体系
Set:无需不可重复的体系
List:有序可重复的集合
Map:具有映射关系的集合
Collection
Collection:
是java中的一个有关集合的接口,Set与List均为其子接口,因此其中的大多数方法都适用于各种Set和List类型的集合
方法摘要:
以下截图于JDK—API 1.6.0文档
以上方法中有关涉及到对象的比较,对比,是否相等之类,都以equals方法为准,所以不要忘记使用的时候重写equals方法。
常用实体类:
ArrayList、HashSet、TreeSet等。
Set
Set:
在java中set类型的集合最显著的特点就是,其中的元素不能重复,如果俩个元素是相等的那么set集合只会存入一个。(以上判别取决于equals方法)。
另外,Set中的元素是没有顺序的。
HashSet:
是Set类型集合的一个经典实现实体类。
- 存储特点:其以哈希表的存储方式存储集合元素,使其查找更加迅速,不能保证元素的位置,另外其不是线程安全的,集合元素也可以是null(哈希表的缘故)。值得注意的是,HashSet储存元素是根据HashCode来决定的,也就是说,要使用HashSet,需要去手动改写添加元素的HashCode。
- 元素重复的可能:并且,当俩个相同元素,其HashCode所返回的值不同的时候,HashSet依然会把他们都存到这个集合中,所以就造成了违背Set原则的情况,因此在写HashCode时需要注意这种情况。
- HashCode的写法:首先我们要用到元素中的属性,直接将每个属性加起来,生成自己的哈希码,固然简单粗暴,但是重复率可能会很大,那么我们让一个质数去乘上元素的一个值,再让结果和其他值相加,这样就可以大大减小重复率了。
LinkedHashSet:
- 存储特点:作为HashSet的一个子类,与HashSet很相似,都是以HashCode去决定元素的存储,但其在存储时使用了链表,使得存储时保证了元素存入的顺序,但这同时也导致其添加元素的速率下降。
TreeSet
- 特点:TreeSet是一个自动排序的集合,元素一边存储,其一边排序,以下说明内部排序和外部排序。
- 内部排序:TreeSet的内部排序要求元素实现Comparable接口,该接口中只有一个方法compareTo;,每当TreeSet添加新元素的时候,集合都会调用元素的compareTo方法去让当前元素和集合中的每一个元素相比较,进而决定当前元素应该放在集合中的什么位置。
- compareTo:这个方法是比较俩个对象谁前谁后的标准,其返回值为int型,若返回一个整数则代表当前元素大,若返回0则代表俩个元素相等,若返回复数则代表当前元素小。重写时应注意,让方法的参数为Object以接受所有类型对象,在方法体中再对所比较对象进行强制类型转换,转换成需要比较的类型去使用,若不能转换则让方法报错,并不再执行元素属性比较。
- 内部排序代码举例:如下为java的一段举例代码,学生类有俩个属性,一个年龄,一个名字,按年龄从小到大排序,代码和运行结果如下
public class Student implements Comparable{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Object obj)
{
Student stu = (Student)obj;
if(this.age>stu.age)
{
return 1;
}
else {
if(this.age<stu.age)
{
return -1;
}
}
return 0;
}
}
public class MainClass {
public static void main(String[] args) {
TreeSet<Student> treeSet= new TreeSet<Student>();
Student stu1 = new Student("AA", 12);
Student stu2 = new Student("ds", 15);
Student stu3 = new Student("Asa", 10);
Student stu4 = new Student("ad", 9);
Student stu5 = new Student("Acx", 18);
treeSet.add(stu1);
treeSet.add(stu2);
treeSet.add(stu3);
treeSet.add(stu4);
treeSet.add(stu5);
for(Student stu:treeSet)
{
System.out.println(stu);
}
}
}
-
外部排序:TreeSet外部排序要求在创建TreeSet对象时给其传递一个Comparator的对象,这个对象我们通常使用匿名内部类来创建,即在new时再为其写入方法的实现。
-
Comparator<T:作为一个接口来说,comparator仅有俩个方法,我们在使用外部排序方法的时候需要实现 方法compare
int compare(T o1, T o2) : 比较用来排序的两个参数。 实现该方法时,首先我们令参数类型为Object,然后在方法体中对其进行强制类型转换,若无法转换则抛出异常,若转换成功则与compareTo类似,比较后返回正负0来决定元素大小关系。当然,也可以在创建Comparator的时候使用泛型,将元素规定好。 -
特点:这种比较方法的特点在于不需要让元素去实现Comparable接口,并且让代码的耦合性降低。而且可以创建多个不同的匿名内部类来作为TreeSet的参数,让程序在执行时更加方便切换排序方式。
-
常用方法:
由于其实现于Set接口所以Set接口的绝大多数方法都可以使用,即也可以使用Collection 的绝大多数方法。
额外的常用方法还有
E first() :返回此 set 中当前第一个(最低)元素。
E floor(E e) :返回此 set 中小于等于给定元素的最大元素;如果不存在这样的元素,则返回 null。
Comparator<? super E> comparator() :返回对此 set 中的元素进行排序的比较器;如果此 set 使用其元素的自然顺序,则返回 null。
E first() :返回此 set 中当前第一个(最低)元素。
E floor(E e) :返回此 set 中小于等于给定元素的最大元素;如果不存在这样的元素,则返回 null。 -
外部排序代码举例:
public class Student{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
public class MainClass {
public static void main(String[] args) {
Comparator<Student> comparator = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge()-o2.getAge();
}
};
TreeSet<Student> treeSet= new TreeSet<Student>(comparator);
Student stu1 = new Student("AA", 12);
Student stu2 = new Student("ds", 15);
Student stu3 = new Student("Asa", 10);
Student stu4 = new Student("ad", 9);
Student stu5 = new Student("Acx", 18);
treeSet.add(stu1);
treeSet.add(stu2);
treeSet.add(stu3);
treeSet.add(stu4);
treeSet.add(stu5);
for(Student stu:treeSet)
{
System.out.println(stu);
}
}
}
List
List:
list型结构是一个有顺序的,可以重复的集合,在list中每一个元素按照加入顺序,会有自己的索引,可以简单的理解为一个随时扩容的数组。
ArrayList:
- ArrayList:是List接口的一个典型实现类,通常我们都使用这个类作为list结构来使用。
- 构造方法:
ArrayList() :构造一个初始容量为 10 的空列表。
ArrayList(Collection<? extends E> c) :构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
ArrayList(int initialCapacity) :构造一个具有指定初始容量的空列表。 - 常用方法:
boolean add(E e) :将指定的元素添加到此列表的尾部。
void add(int index, E element) :将指定的元素插入此列表中的指定位置,然后本来在这个位置的元素向后延顺。
boolean addAll(Collection<? extends E> c) :按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。
boolean addAll(int index, Collection<? extends E> c) : 从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。
int size() :返回此列表中的元素数。
E set(int index, E element) :用指定的元素替代此列表中指定位置上的元素。
boolean isEmpty() :如果此列表中没有元素,则返回 true
E remove(int index) : 移除此列表中指定位置上的元素。
boolean contains(Object o) :如果此列表中包含指定的元素,则返回 true。