1. List接口
实现了List
接口的对象称为List集合。在List集合中允许出现重复的元素,所有的元素是以一种线性方式进行存储的,在程序中可以通过索引来访问集合中的指定元素。另外,List集合还有一个特点就是元素有序,即元素的存入顺序和取出顺序一致。
List接口特点:
- 它是一个元素存取有序的集合。例如,存元素的顺序是11、22、33。那么集合中,元素的存储就是按照11、22、33的顺序完成的)。
- 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。
- 集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。
import java.util.ArrayList;
import java.util.List;
/*
- `public void add(int index, E element)`: 将指定的元素,添加到该集合中的指定位置上。
- `public E get(int index)`:返回集合中指定位置的元素。
- `public E remove(int index)`: 移除列表中指定位置的元素, 返回的是被移除的元素。
- `public E set(int index, E element)`:用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
*/
public class test {
public static void main(String[] args) {
List<String> li=new ArrayList<>();
li.add("a");
li.add("b");
li.add("c");
li.add("a");
System.out.println(li);
li.add(2,"cc");
System.out.println(li);
String s1 = li.get(1);
System.out.println(s1);
String remove1 = li.remove(2);
System.out.println(remove1);
System.out.println(li);
String c1 = li.set(2, "ccc");
System.out.println(c1+","+li);
for (int i = 0; i < li.size(); i++) {
System.out.println(li.get(i));
}
}
}
1.1. LinkedList
LinkedList是一个双向链表。
import java.util.LinkedList;
/*
* `public void addFirst(E e)`:将指定元素插入此列表的开头。
* `public void addLast(E e)`:将指定元素添加到此列表的结尾。等效于add
* `public void push(E e)`:将元素推入此列表所表示的堆栈。等效于addFirst
*
* `public E getFirst()`:返回此列表的第一个元素。
* `public E getLast()`:返回此列表的最后一个元素。
*
* `public E removeFirst()`:移除并返回此列表的第一个元素。
* `public E removeLast()`:移除并返回此列表的最后一个元素。
* `public E pop()`:从此列表所表示的堆栈处弹出一个元素。等效于removeFirst
*
* `public boolean isEmpty()`:如果列表不包含元素,则返回true。
*/
public class test {
public static void main(String[] args) {
LinkedList<String> lin=new LinkedList<>();
lin.add("a");
lin.add("b");
lin.add("c");
System.out.println(lin);
lin.addFirst("-a");
System.out.println(lin);
lin.push("-aa");
System.out.println(lin);
String first1 = lin.getFirst();
System.out.println(first1);
String last1 = lin.getLast();
System.out.println(last1);
lin.pop();
System.out.println(lin);
lin.removeFirst();
System.out.println(lin);
lin.removeLast();
System.out.println(lin);
boolean empty1 = lin.isEmpty();
System.out.println(empty1);
}
}
2. Set
与List
接口不同的是,Set
接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。
2.1. HashSet
import java.util.HashSet;
import java.util.Iterator;
public class test {
public static void main(String[] args) {
HashSet<String> has = new HashSet<>();
has.add("a");
has.add("c");
has.add("b");
has.add("a");
//不允许重复元素,取出顺序与添加顺序无关
//无索引,不能使用for循环遍历,但可用增强for
Iterator<String> it = has.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
哈希表
在JDK1.8之前,哈希表底层采用 数组+链表 实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,哈希表存储采用 数组+链表+红黑树 实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。
HashSet存储自定义类型元素
给HashSet中存放自定义类型元素时,需要重写对象中的hashCode和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一。
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Student(String name, int age) {
this.name = name;
this.age = 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;
}
}
import java.util.HashSet;
import java.util.Iterator;
public class test {
public static void main(String[] args) {
Student s1=new Student("张三",18);
Student s2=new Student("张三",18);
Student s3=new Student("张三",19);
HashSet<Student> ss = new HashSet<>();
ss.add(s1);
ss.add(s2);
ss.add(s3);
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s3.hashCode());
System.out.println(s1==s2);
System.out.println(s1.equals(s2));//添加equals和hashCode后为true
Iterator<Student> si = ss.iterator();
while(si.hasNext()){
System.out.println(si.next());
}
}
}
2.2 LinkedHashSet
import java.util.HashSet;
import java.util.LinkedHashSet;
/*
* LinkedHashSet底层是哈希表(数组+链表/红黑树)+链表(记录元素存储顺序),保证元素有序
* */
public class test {
public static void main(String[] args) {
HashSet<String> has = new HashSet<>();
has.add("www");
has.add("aaa");
has.add("aaa");
has.add("com");
System.out.println(has);
LinkedHashSet<String> lhas=new LinkedHashSet<>();
lhas.add("www");
lhas.add("aaa");
lhas.add("aaa");
lhas.add("com");
System.out.println(lhas);
}
}