集合
集合框架
Collection
List: ArrayList, LinkedList, Vector
Set: HashSet, TreeSet
每一个容器对数据的存储方式都有不同,这个存储方式称为数据结构。
list
: 元素是有序的。元素可以重复,因为该集合有索引。
set
:元素是无序的。
List
:集合特有的迭代器, ListIterator是Iterator的子接口。
在迭代时, 不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。
所以,在迭代时,只能用迭代器的方法操作元素,可是Iterator的方法是有限的,只能对元素进行判断,去除,删除的操作,如果想要进行其他的操作如添加,修改等会,就需要使用其子接口,ListIterator.
该接口只能通过List集合的ListIterator方法获取。
//ArrayList判断元素是否相同以来的是元素的equals方法
List<String> li = new ArrayList<String>();
li.add("java1111");
li.add("java2222");
li.add("java3333");
li.add("java4444");
System.out.println(li);
ListIterator<String> it2 = li.listIterator();
while(it2.hasNext()) {
Object obj = it2.next();
if (obj.equals("java3333")) {
it2.add("hahahahah");
System.out.println("it2: " + obj);
}
}
System.out.println("li2" + li);
ArrayList
:底层使用的是数组结构。特点: 查询速度很快,但是增删稍慢。线程不同步。
LinkedList
:底层使用的是链表数据结构。特点: 增删很快,但是查询稍慢。
Vector
: 底层是数组数据结构。 线程同步。被ArrayList替代了。
LinkedList
/*
特有方法: getFirst(); getLast(); 获取元素但是不会删除元素
addFirst(); addLast();
removeFirst(); removeLast(); 获取元素,但是元素会被删除。如果集合中没有元素会出现NoSuchElementException
JDK1.6中出现替代方法。
offerFirst();
offerLast();
peekFirst()
peekLast()
pollFirst()
pollLast();获取元素,但是元素会被删除。如果集合中没有元素会返回null
*/
LinkedList<String> link = new LinkedList<>();
link.addFirst("java001");
link.addLast("java002");
System.out.println("first: " + link.removeFirst());
System.out.println(link.pollFirst());
用LinkedList模仿队列:
//队列先进先出
public class Queue {
private LinkedList link;
public Queue () {
link = new LinkedList();
}
public void myAdd(Object obj) {
link.addFirst(obj);
}
public Object myGet() {
return link.removeLast();
}
public boolean isNull() {
return link.isEmpty();
}
}
List中的比较底层都是用的equals方法。
Set集合
Set: 元素是无序的,元素不可以重复。
常见子类:
HashSet: 底层数据结构是hash表, 线程不同步
HashSet 保证元素唯一性: 是通过元素的两个方法, hashCode和equals来完成。
如果元素的HashCode值相同,才会判断equals是否为true
如果元素的hashCode值不同,不会调用equals方法。
注意, 对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法
TreeSet: 可以对Set中的元素排序
底层数据结构是二叉树
保证元素唯一性的依据: compareTo方法 return 0;
TreeSet排序的第一种方式: 让元素自身具备比较性,覆盖compareTo方法,
这种方式也称之为元素的默认顺序,或者叫做自然顺序。
TreeSet集合的第二种排序方式:当元素自身不具备比较性是,或者具备的比较性不是所需要的,这时需要让集合吱声具备比较性。定义比较器,将比较器作为参数传递给TreeSet集合的构造函数。
当两种排序都存在是,以比较器为主。
记住: 排序,当主要条件相同时,一定要判断次要条件
泛型
Java1.5 出现,提高安全性
只要见到<>就要定义泛型。 其实<>就是用来接收类型的
//当类中操作的引用数据类型不确定的时候
//早期定义Object来完成扩展
//现在定义泛型来完成扩展
public class Tools<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
Map集合
Map
包括HashMap, TreeMap, HashTable
- HashTable: 底层是哈希表数据结构, 不可以存入null键null值, 该集合线程同步
- HashMap: 底层是哈希表数据结构, 允许使用null键和null值,该集合线程不同步
- TreeMap: 底层是二叉树结构,线程不同步,可以用于给map集合中的键进行排序。
Set集合底层就是使用的Map集合
Map
集合存储键值对,一对一的往里面存,而且保持键的唯一性。
添加
put(key, value)
删除
clear();
判断
containKey(Object key), containValue(),
获取
get(Object key) , size(), values(), entrySet(), keySet();
keySet: 将Map中所有的键存入到Set集合。因为Set集合具备迭代器,所以可以用迭代方式去除所有的键,再根据get方法,获取每一个键对应的值。
Map集合的取出原理:将Map集合转换成Set集合,再通过迭代器取出。
Set<Map.Entry<K, V>> entrySet
: 获取映射关系,通过getKey(), getValue()方法获取所有键和所有值Map.Entry 其实Entry也是一个接口,它是Map接口中的一个内部接口。
TreeSet
实现排序,元素唯一。
- 自定义类
//自定义类
package map;
public class Student implements Comparable<Student>{
private String name;
private String age;
Student(String name, String age ) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((age == null) ? 0 : age.hashCode());
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;
Student other = (Student) obj;
if (age == null) {
if (other.age != null)
return false;
} else if (!age.equals(other.age))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public int compareTo(Student o) {
int num = this.age.compareTo(o.age);
if (num == 0) {
this.name.compareTo(o.name);
}
return num;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
实现自己的比较器
package map; import java.util.Comparator; public class TreeMapComparetor implements Comparator<Student>{ //实现自己的比较器 @Override public int compare(Student s1, Student s2) { int num = s1.getName().compareTo(s2.getName()); if (num == 0) { return s1.getAge().compareTo(s2.getAge()); } return num; } }
将比较器传入TreeMap中实现自定义比较
package map; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; public class TreeMapDemo { public static void main(String[] args) { TreeMap<Student, String> tm = new TreeMap<>(new TreeMapComparetor()); tm.put(new Student("zhangsan", "21"), "shenzhen"); tm.put(new Student("lisi", "22"), "shenzhen"); tm.put(new Student("gangwu", "21"), "shenzhen"); tm.put(new Student("wuliu", "26"), "shenzhen"); tm.put(new Student("zhouer", "24"), "shenzhen"); tm.put(new Student("zhouer", "20"), "shenzhen"); Iterator<Entry<Student, String>> it = tm.entrySet().iterator(); while(it.hasNext()) { System.out.println(it.next().getKey().toString()); } } } //输出打印 实现排序 // Student [name=gangwu, age=21] // Student [name=lisi, age=22] // Student [name=wuliu, age=26] // Student [name=zhangsan, age=21] // Student [name=zhouer, age=20] // Student [name=zhouer, age=24]
集合框架工具类Collections
常用方法:
public class CollectionsDemo { public static void main(String[] args) { //sortDemo(); //maxDemo(); //binarySearchDemo(); orderDemo() ; } //反转顺序 public static void orderDemo() { TreeSet<String> ts = new TreeSet<>(Collections.reverseOrder()); ts.add("aaa"); ts.add("dsfd"); ts.add("eggg"); ts.add("rewrwe"); Iterator<String> it = ts.iterator(); while(it.hasNext()) { System.out.println(it.next()); } } //集合二分查找 public static void binarySearchDemo() { List<String> list = new ArrayList<>(); list.add("sdsd"); list.add("d"); list.add("fsdfsdfsfs"); list.add("fgd"); //随机打乱顺序 Collections.shuffle(list); System.out.println("1: " + list); int index = Collections.binarySearch(list, "d"); System.out.println("index: " + index); } public static void maxDemo() { List<String> list = new ArrayList<>(); list.add("sdsd"); list.add("d"); list.add("fsdfsdfsfs"); list.add("fgd"); System.out.println("1: " + list); String max = Collections.max(list, new CollectionsDemo().new StrLenComparator()); System.out.println("max: " + max); } //排序 public static void sortDemo() { List<String> list = new ArrayList<>(); list.add("sdsd"); list.add("d"); list.add("fsdfsdfsfs"); list.add("fgd"); System.out.println("1: " + list); Collections.sort(list, new CollectionsDemo().new StrLenComparator()); System.out.println("2: " + list); //输出结果:1: [sdsd, d, fsdfsdfsfs, fgd] 2: [d, fgd, sdsd, fsdfsdfsfs] } class StrLenComparator implements Comparator<String> { @Override public int compare(String o1, String o2) { if (o1.length() > o2.length()) { return 1; } else if (o1.length() < o2.length()) { return -1; } return o1.compareTo(o2); } } }
JDK1.5一些新特性
public class ArraysDemo { public static void main(String[] args) { Integer[] array = {1, 2, 3}; List<Integer> li = Arrays.asList(array); System.out.println(li); String[] strArr = {"aaaa", "bbb", "ccc"}; List<String> list = asList(strArr); list.contains("ccc"); //不能使用集合的增删方法, 因为数组长度是固定的 //list.add("ddd"); /** * 如果数组中的元素都是对象, 那么变成集合时,数组中的元素就直接转成集合中的元素 * 如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。 */ /** * 集合变数组: 为了限定对元素的操作。不需要进行增删 */ } /** * 可变参数 */ public static void show(String... a) { } /** * java1.5 新特性 * 静态导入 */ }