集合
集合的特点:
1.集合可以存放不同类型的对象(只能存放对象),数组只能存放同一类型的数据,但是可以存放基本类型的数据
2.集合的长度可以自动增加,数组的长度一旦确定,就不能再改变
3.集合对象中有众多方法可以直接调用进行数据的操作,数组对象中没有方法可以对数据进行操作
4.java.util包中的Collections工具类可以对集合中的元素进行操作。同样java.util中的Arrays工具类可以对数组中的元素进行操作
Iterable接口
实现这个接口的对象,可以使用foreach语句对其进行循环遍历,并且该接口中提供了一个方法可以返回迭代器对象,迭代器对象在这里的作用就是循环遍历集合中的每一个元素。public Iterator iterator();
Iterable接口中的forEach方法:
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
Collection接口
通过查看源码可知,Collection接口继承了Iterable接口。
public interface Collection<E> extends Iterable<E>
JDK中不提供此接口的任何直接实现,而是提供更具体的子接口(List和Set)
Collection接口中提供了很多集合中通用的方法。
Collection类型集合的遍历
1.通过使用集合中提供的迭代器
public class Test {
public static void main(String[] args) {
Collection<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
2.List集合特有的方式,通过get获取元素的下标访问元素
public class Test {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
for(int i=0;i<list.size();i++) {
System.out.println(list.get(i));
}
}
}
3.forEach循环
public class Test {
public static void main(String[] args) {
Collection<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
for(Integer o:list) {
System.out.println(o);
}
}
}
List接口和Set接口
List接口和Set接口都是Collection接口的子接口。
List:集合中的元素有序可重复
Set:集合中的元素不可重复,是否有序要看Set接口具体的实现类
注:有序指的是存放的顺序与取出的顺序是否一致。
List接口的常见实现类
ArrayList,LinkedList,Vector
1.ArrayList是实现的基于动态数组的数据结构,LinkedList是基于链表的数据结构
2.对于数据的随机访问,ArrayList的效率高于LinkedList,因为LinkedList要移动指针
3.对于新增或者删除操作,LinkedList优于ArrayList,因为ArrayList要移动数据。
4.Vector是线程安全的集合,但是速度慢
Set接口常见的实现类
HashSet和LinkedHashSet
HashSet集合中元素的特点:无序不可重复
LinkedHashSet中元素的特点:有序不可重复
用代码验证一下Set集合中元素的无序
public class Test {
public static void main(String[] args) {
Collection<Integer> list = new HashSet<Integer>();
list.add(1);
list.add(3);
list.add(2);
list.add(4);
for(Integer o:list) {
System.out.print(o);
}
}
}
输出结果是
1234
再对比一下LinkedHashSet
public class Test {
public static void main(String[] args) {
Collection<Integer> list = new LinkedHashSet<Integer>();
list.add(1);
list.add(3);
list.add(2);
list.add(4);
for(Integer o:list) {
System.out.print(o);
}
}
}
输出结果
1324
SortedSet接口和TreeSet类
1.SortedSet接口是Set接口的子接口,提供了排序的功能,TreeSet类就是SortedSet接口的实现类。
2.TreeSet类的排序功能
TreeSet排序永远都是从小到大,但是谁大谁小是我们说了算。
自然排序
让元素自身具备比较性,需要实现Comparable接口,重写其中的compareTo方法。
public class Test {
public static void main(String[] args) {
TreeSet<Student> set = new TreeSet<Student>();
set.add(new Student(3,12));
set.add(new Student(2,13));
set.add(new Student(4,10));
set.add(new Student(1,15));
Iterator<Student> it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
class Student implements Comparable<Student>{//实现了Comparable接口
private int id;
private int age;
public Student(int id,int age) {
this.id=id;
this.age=age;
}
@Override
public int compareTo(Student o) {//重写compareTo方法
if(this.id<o.id) {
return -1;
}
else {
return 1;
}
}
@Override
public String toString() {
return "Student [id=" + id + ", age=" + age + "]";
}
}
输出结果根据年龄升序
Student [id=1, age=15]
Student [id=2, age=13]
Student [id=3, age=12]
Student [id=4, age=10]
比较器排序
使用比较器进行元素之间的比较,比较器排序的优先级比自然排序的高
public class Test {
public static void main(String[] args) {
TreeSet<Student> set = new TreeSet<Student>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.getId()-o1.getId();
}
});
set.add(new Student(3,12));
set.add(new Student(2,13));
set.add(new Student(4,10));
set.add(new Student(1,15));
Iterator<Student> it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
class Student implements Comparable<Student>{
private int id;
private int age;
public Student(int id,int age) {
this.id=id;
this.age=age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(Student o) {
if(this.id<o.id) {
return -1;
}
else {
return 1;
}
}
@Override
public String toString() {
return "Student [id=" + id + ", age=" + age + "]";
}
}
输出结果根据年龄降序
Student [id=4, age=10]
Student [id=3, age=12]
Student [id=2, age=13]
Student [id=1, age=15]
比较器排序可以根据自己的选择来进行排序,无需重写Student类。
Collection类型集合与数组之间的转换
Collection接口中定义了两个方法,可以把当前集合转换成数组
Object[] toArray()
返回包含集合中所有元素的数组
例如:
Collection c = new ...;
(List或者Set的实现类都可以)
Object[] array = c.toArray();
System.out.println(Arrays.toString(array));
<T> T[] toArray(T[] a)
可指定返回数组的类型
例如:
Collection c = new ...;
(List或者Set的实现类都可以)
String[] str = new String[set.size()];
//元素自动存放到数组str中了
set.toArray(str);
System.out.println(Arrays.toString(str));
java.util.Arrays中定义了一个方法,可以将数组转换为List类型集合
public static <T> List<T> asList(T... a)
Map
Map类型的集合与Collection类型的集合不同,Map类型的集合存储数据的时候使用Key-Value的形式,且Key值不能重复,否则会覆盖原来的键值对。
Map接口的常用实现类
HashMap和Hashtable类
1.HashMap是线程不安全的,Hashtable是线程安全的
2.HashMap允许key值、value值为null,但是Hashtable中的key和value都不允许为null,否则会报错
Map类型集合的遍历
1.使用keyset方法,可以返回Map集合中所有key值的set集合
public class Test {
public static void main(String[] args) {
Map<String,Student> map = new HashMap<String,Student>();
map.put("1", new Student());
map.put("2", new Student());
map.put("3", new Student());
map.put("4", new Student());
for(String key:map.keySet()) {
System.out.println(key);
}
}
}
class Student{
}
2.使用values方法,可以返回Map集合中所有value值的Collection类型集合
public class Test {
public static void main(String[] args) {
Map<String,Student> map = new HashMap<String,Student>();
map.put("1", new Student());
map.put("2", new Student());
map.put("3", new Student());
map.put("4", new Student());
for(Student value:map.values()) {
System.out.println(value);
}
}
}
class Student{
}
3.使用entrySet方法,可以返回该Map集合中,包含所有Entry类型对象的Set集合
public class Test {
public static void main(String[] args) {
Map<String,Student> map = new HashMap<String,Student>();
map.put("1", new Student());
map.put("2", new Student());
map.put("3", new Student());
map.put("4", new Student());
Set<Entry<String, Student>> set = map.entrySet();
for(Entry e:set) {
System.out.println(e.getKey());
System.out.println(e.getValue());
}
}
}
class Student{
}
SortedMap接口和TreeMap类
SortedMap接口是Map的子接口,其进一步提供对于键的排序功能。
TreeMap类就是SortedMap接口的实现类。
TreeMap可以对key值进行自然排序或者比较器排序,其用法和TreeSet是一致的。