JAVA集合
分成两个体系(Collection和Map)
Collection接口
单列集合,定义了存取一组对象的方法的集合
Collection接口的常用方法
@Test
public void test1(){
Collection collection=new ArrayList();
//方法1
collection.add("AA");
collection.add("BB");
collection.add(123);
collection.add(new Date());
//方法2
System.out.println(collection.size());
Collection collection1=new ArrayList();
collection1.add("CC");
collection1.add("DD");
//方法3
collection.addAll(collection1);
System.out.println(collection);
//方法4
collection.clear();
//方法5
System.out.println(collection.isEmpty());
}
@Test
public void test2(){
Collection coll=new ArrayList();
coll.add("aa");
coll.add("bb");
coll.add(123);
coll.add(new Date());
coll.add(new String("abc"));
Collection coll1=new ArrayList();
coll1.add("aa");
coll1.add("bb");
coll1.add(123);
coll1.add(new Date());
//方法7
boolean contains2 = coll.containsAll(coll1);//两个集合需要一模一样,可理解克隆
System.out.println("containsAll测试:"+contains2);
Person tom = new Person("Tom", 90);
coll.add(tom);
coll.add(new Person("tom",21));
//方法8
boolean contains = coll.contains(123);
boolean contains1 = coll.contains(tom);
System.out.println(coll.contains(new Person("tom", 21)));//需要重写equals方法
System.out.println(contains1);
System.out.println(contains);
}
@Test
public void test3(){
Collection coll=new ArrayList();
coll.add(123);
coll.add("abc");
coll.add(new String("ddd"));
coll.add(false);
coll.add(new Person("Tom",21));
Collection coll1=new ArrayList();
coll1.add("abc");
coll1.add(new String("ddd"));
//方法9
coll.remove(123);
System.out.println(coll);
//方法10
coll.removeAll(coll1);
System.out.println(coll);
}
@Test
public void test4(){
Collection coll=new ArrayList();
coll.add("abc");
coll.add("dddd");
coll.add("hhg");
coll.add("sss");
Collection coll1=new ArrayList();
coll1.add("abc");
coll1.add("dddd");
coll1.add("hhg");
coll1.add("sss");
//方式11
System.out.println(coll.equals(coll1));
//方法12
System.out.println(coll.hashCode());
//方法13
Object[] objects = coll.toArray();
for (int i = 0; i < objects.length; i++) {
System.out.print(objects[i]+"\t");
}
System.out.println();
//数组--->集合
List integers = Arrays.asList(123, 898);
System.out.println(integers);
System.out.println(integers.size());
List<Integer> integers1 = Arrays.asList(new Integer[]{123,456});
for (Integer integer1:integers1){
System.out.println(integer1.toString());
}
System.out.println(integers1.size());
}
迭代器,遍历集合
hasNext()和next()
@Test
public void test1(){
Collection coll=new ArrayList();
coll.add("abc");
coll.add("dddd");
coll.add("hhg");
coll.add("sss");
Iterator iterator = coll.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
@Test
public void test2(){
String[] arr=new String[]{"MM","MM","MM"};
// for(int i=0;i<arr.length;i++){
// arr[i]="GG";
// }
for (String string:arr){
string="GG";
}
for (String s:arr){
System.out.println(s);
}
}
List
元素有序、可重复的集合
ArrayList
线程不安全的,效率高
ArrayList list=new ArrayList();此时底层数组长度为0,当调用list.add(Object o)时,底层数组长度为10,并将数据添加到数组中;
如果添加数据超过10时,对数组容量进行扩容,扩容为原来容量的1.5倍,同事将原有数组的数据复制到新的数组。
1.7:1.7是在new对象的时候直接创建了一个长度为10的数组,1.7有点类似于饿汉式,1.8有点类似于懒汉式
//add(Object obj)
//remove(int index)/remove(Object obj)
//set(int index,Object obj)
//get(int index)
@Test
public void test1(){
List list=new ArrayList();
//方法1
list.add(123);
list.add("123");
list.add("aaa");
list.add("bbb");
list.add("ccc");
//方法2
list.remove(1);
list.remove("aaa");
//方法3
list.set(0,"456");
//方法4
Object o = list.get(0);
System.out.println(o);
System.out.println(list);
List list1=new ArrayList();
list1.add(123);
list1.add("123");
list1.add("aaa");
list1.add("bbb");
list1.add("ccc");
list.addAll(list);
System.out.println(list);
}
LinkedList
内部声明了Node类型的first和last属性,调用add方法时候将数据封装到Node中,创建了Node对象
Vector
线程安全的,效率低
Set
元素无序、不可重复的集合
无序性
不等于随机性,存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值
不可重复性
保证添加的元素按照equals()判断时,不能返回true,即相同的元素只能添加一个
@Test
public void test1(){
Set set=new HashSet<>();
set.add(123);
set.add("aa");
set.add(new Person("tom",12));
set.add(new Person("tom",12));
set.add("cc");
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
在添加元素时,以HashSet为例
添加元素a时,调用元素a所在类的hashCode()方法,计算元素a的哈希值,通过某种方法计算出HashSet底层数组中的存放位置,判断数组此位置上是否有元素
如果此位置上没有元素则添加成功
如果此位置上有元素则比较哈希值
如果哈希值不同,则添加成功
如果哈希值相同则调用元素a所在类的equals()方法
如果返回为false,则添加成功
如果返回true则添加失败
1.7是元素a指向原有的数据,1.8是原来的数据指向元素a(七上八下)
HashSet底层:数组+链表
HashSet
Set主要实现类,线程不安全的,可以存储null值
LinkedHashSet
作为HashSet的子类,遍历其内部结构时,可以按照添加的顺序
@Test
public void test2(){
Set set=new LinkedHashSet();
set.add(123);
set.add("aaa");
set.add("ccc");
set.add(new Person("Tom",21));
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
TreeSet
可以按照添加对象的指定属性,进行排序
向TreeSet添加的数据,必须是相同类型的对象
两种排序方式
自然排序(实现Comparable接口)和定制排序(Comparator)
自然排序中,比较两个对象是否相同的标准为:compareTo()返回0,不再是equals()
//实现接口Comparable,实现方法comparaTo(Object obj)
@Override
public int compareTo(Object o) {
if (o instanceof Person){
Person person= (Person) o;
if (this.name.compareTo(person.name)!=0){
return this.name.compareTo(person.name);
}else {
return Integer.compare(this.age,person.age);
}
}else {
throw new RuntimeException("输入的类型不匹配");
}
}
@Test
public void test3(){
Set set=new TreeSet();
set.add(new Person("Abandon",321));
set.add(new Person("Jack",213));
set.add(new Person("Jacky",31));
set.add(new Person("Dolly",21));
set.add(new Person("Delly",2));
set.add(new Person("Delly",12));
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
//定制排序
@Test
public void test5(){
Set set=new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Employee && o2 instanceof Employee){
Employee e1= (Employee) o1;
Employee e2= (Employee) o2;
MyDate m1= e1.getMyDate();
MyDate m2= e2.getMyDate();
if (m1.getYear()-m2.getYear()!=0){
return m1.getYear()-m2.getYear();
}else {
if (m1.getMonth()- m2.getMonth()!=0){
return m1.getMonth()- m2.getMonth();
}
}
return m1.getDay()- m2.getDay();
}
return 0;
}
});
set.add(new Employee("刘德华",55,new MyDate(1965,5,4)));
set.add(new Employee("张学友",50,new MyDate(1970,8,4)));
set.add(new Employee("郭富城",45,new MyDate(1977,5,4)));
set.add(new Employee("黎明",43,new MyDate(1974,5,4)));
set.add(new Employee("梁朝伟",53,new MyDate(1974,5,12)));
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
Map接口
双列集合,保存具有映射关系”key-value对“的集合
HashMap
线程不安全,效率高,存储null的key和value
jdk7底层源码分析
Map map=new HashMap();
在实例化以后,底层创建了一个长度为16的一维数组Entry[] table
map.put(key1,value1)
调用key1所在类的hashCode()计算key1哈希值,放在Entry数组中的对应位置
如果此位置上的位置为空,在添加成功
如果此位置上的位置不为空,比较哈希值
如果key1的哈希值与已经存在数据的哈希值不相同,则添加成功
如果key1的哈希值与已经存在数据的哈希值相同,比较equals()
如果equals返回false则添加成功
如果equals返回true使用value1代替原来的数据
扩容为原来的两倍
相较于jdk7,jdk8的不同
Map map=new HashMap(),此时没有创建数组
在第一次调用put()方法时,底层创建长度为16的数组
jdk8中HashMap中底层数组是;Node[]
jdk7底层结构:数组+链表,jdk8底层结构:数组+链表+红黑树
当数组的个数>8且数组长度>64时,此时所有数据改为红黑树存储
@Test
public void test1(){
Map map=new HashMap();
//方法1
map.put("AA",111);
map.put("BB",222);
map.put("CC",333);
map.put("DD",444);
map.put("AA",555);
System.out.println(map);
Map map1=new HashMap();
map1.put("EE",666);
map1.put("FF",777);
//方法2
map.putAll(map1);
System.out.println(map);
//方法3
Object value = map.remove("FF");
System.out.println(value);
System.out.println(map);
//方法4
map.clear();
//方法5
System.out.println(map.size());
}
@Test
public void test2(){
Map map=new HashMap();
map.put("AA",111);
map.put("BB",222);
map.put("CC",333);
map.put("DD",444);
map.put("AA",555);
//方法6
Object value = map.get("AA");
System.out.println(value);
//方法7
boolean isExist = map.containsKey("BB");
System.out.println(isExist);
//方法8
isExist=map.containsValue(555);
System.out.println(isExist);
//获取map的key集
Set set = map.keySet();
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//获取map所有的value
Collection values = map.values();
Iterator iterator1 = values.iterator();
while (iterator1.hasNext()) {
System.out.println(iterator1.next());
}
//获取所有key-value
Set entrySet = map.entrySet();
Iterator iterator2 = entrySet.iterator();
while (iterator2.hasNext()) {
// System.out.println(iterator2.next());
Object next = iterator2.next();
Map.Entry entry = (Map.Entry) next;
System.out.println(entry.getKey()+"======"+entry.getValue());
}
}
LinkedHashMap
可以按照添加的顺序实现遍历
TreeMap
保证按照添加的key-value对进行排序,此时考虑key的自然排序或定制排序,底层使用红黑树
//自然排序(实现Comparable接口)和定制排序(Comparator)
//自然排序
@Override
public int compareTo(Object o) {
if (o instanceof Person){
Person person= (Person) o;
if (this.name.compareTo(person.name)!=0){
return this.name.compareTo(person.name);
}else {
return Integer.compare(this.age,person.age);
}
}else {
throw new RuntimeException("输入的类型不匹配");
}
}
@Test
public void test3(){
//定制排序
Map map=new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Person && o2 instanceof Person){
Person p1= (Person) o1;
Person p2= (Person) o2;
if (p1.getName().compareTo(p2.getName())!=0){
return -p1.getName().compareTo(p2.getName());
}else {
int compare = Integer.compare(p1.getAge(), p2.getAge());
if (compare!=0){
return compare;
}
}
}
return 0;
}
});
Person p1 = new Person("Tom", 34);
Person p2 = new Person("Jerry", 21);
Person p3 = new Person("Mary", 14);
Person p4 = new Person("Bob", 12);
map.put(p1,90);
map.put(p2,88);
map.put(p3,86);
map.put(p4,92);
System.out.println(map);
}
Hashtable
线程安全的,效率低。不能存储null的key和value
Properties
常用来处理配置文件。key和value都是String类型
public static void main(String[] args) throws Exception {
Properties properties=new Properties();
FileInputStream fis=new FileInputStream("jdbc.properties");
properties.load(fis);
String name = properties.getProperty("name");
String password = properties.getProperty("password");
System.out.println(name);
System.out.println(password);
}
Collections
package day08;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollectionsTest {
@Test
public void test1(){
List list = new ArrayList<>();
list.add(123);
list.add(123);
list.add(123);
list.add(543);
list.add(657);
list.add(563);
System.out.println(list);
//方法1:反转list集合
// Collections.reverse(list);
//方法2:随机排序
// Collections.shuffle(list);
//方法3:排序
// Collections.sort(list);
//方法4:交换指定集合元素之间
// Collections.swap(list,0,1);
//方法5:求此集合最大的元素
Object max = Collections.max(list);
System.out.println(max);
//方法6:求此集合最小的元素
Comparable min = Collections.min(list);
System.out.println(min);
//方法7:求集合里面某元素出现的次数
int times = Collections.frequency(list, 123);
System.out.println(times);
// Collections.sort(list, new Comparator() {
//
// @Override
// public int compare(Object o1, Object o2) {
// Integer i1= (Integer) o1;
// Integer i2= (Integer) o2;
// if (i1.compareTo(i2)!=0){
// return -i1.compareTo(i2);
// }
// return 0;
// }
// });
//方法8:复制此集合到另一个集合中
// List dest=Arrays.asList(new Object[list.size()]);
// Collections.copy(dest,list);
// System.out.println(dest);
//返回线程安全的集合
List list1 = Collections.synchronizedList(list);//此时的list1是线程安全的
System.out.println(list);
}
}