-
集合与数组储存数据概述
集合、数组都是对多个数据进行存储操作的结构,简称Java容器
说明:此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储(.txt .jpg .avi 数据库中)
-
数组存储的特点
- 一旦初始化以后,其长度就确定了
- 数组一旦定义好,其元素的类型也就确定了,我们也就只能操作指定类型的数据了
-
数组存储的弊端
- 一旦初始化后,其长度就不可修改
- 数组中提供的方法非常有限,对于添加、删除、插入数据等操作,非常不便,同时效率不高
- 获取数组中实际元素的个数的需求,数组没有现成的属性或方法可用
- 数组存储数据的特点:有序、可重复。对于无序不可重复的需求,不能满足
-
集合存储的优点
解决数组存储数据方面的弊端
-
Collection接口:单列数据,定义了存取一组对象的方法的集合
-
List:元素有序、可重复的集合 “动态”数组
------ArrayList,linkedList,Vector
-
Set:元素无序、不可重复的集合 高中讲的“集合”
------HashSet、linkedHashSet、TreeSet
-
-
Map接口:双列数据,保存有映射关系“key-value对”的集合(映射 )
------HashMap、linkedHashMap、TreeMap、Hashtable、Properties
public void test1(){
Collection coll = new ArrayList();
//add(Object e)方法 将元素e添加到集合coll中
coll.add("AA");
coll.add("BB");
coll.add(123);
coll.add(new Date());
//size() 获取添加的元素个数
System.out.println(coll.size());//4
//addAll(Collection coll1):将coll1集合中的元素添加到当前集合中
Collection coll1 = new ArrayList();
coll1.add(456);
coll1.add("CC");
coll.addAll(coll1);
System.out.println(coll.size());//6
System.out.println(coll);//[AA, BB, 123, Tue Oct 26 19:04:57 GMT+08:00 2021, 456, CC]
//isEmpty() 判断当前集合是否为空(是否有元素)
System.out.println(coll.isEmpty());//false
//clear() 清空元素
coll.clear();//清空元素
System.out.println(coll.isEmpty());//true
}
contains,containsAll
-
Person类:
public class Person { private String name; private int age; public Person() { } public Person(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; } @Override public String toString() { return "Person{" + "name='" + name + ''' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { System.out.println("Person equals()……"); if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; if (age != person.age) return false; return name != null ? name.equals(person.name) : person.name == null; } } -
测试
public void test2(){ Collection coll = new ArrayList(); //Person person = new Person("小明", 21); coll.add(new String("XP")); coll.add(false); coll.add(123); coll.add(456); coll.add(new Person("小明", 21)); //contains(Object obj)判断当前集合中是否包含obj (调用obj 所在类的equals()方法判断内容) System.out.println(coll.contains(123));//true System.out.println(coll.contains(12));//false System.out.println(coll.contains("XP"));//true System.out.println(coll.contains(new String("XP")));//true System.out.println(coll.contains(new Person("小明", 21)));//false System.out.println(coll); // 重写equals后变成true: //containsAll(Collection coll1)判断形参coll1是否都存在于当前集合中 Collection coll1 = Arrays.asList(123,456); System.out.println(coll.containsAll(coll1));//true }
public void test3(){
Collection coll = new ArrayList();
coll.add("XP");
coll.add(false);
coll.add(123);
coll.add(456);
coll.add(new Person("小明", 21));
//remove(Object obj)移除,若没有指定的元素,则返回false (会调用equals()方法)
System.out.println(coll);//[XP, false, 123, 456, Person{name='小明', age=21}]
System.out.println(coll.remove(123));//true
System.out.println(coll.remove(1234));//false
System.out.println(coll);//[XP, false, 456, Person{name='小明', age=21}]
//removeAll(Collection coll1) 从当前集合中移除coll1中的所共有的元素(获取差集并返回给当前集合)
Collection coll1 = new ArrayList();
coll1.add(1234);
coll1.add(456);
System.out.println(coll.removeAll(coll1));//true
System.out.println(coll);//[XP, false, Person{name='小明', age=21}]
//retainAll 获取当前集合中找出与coll1中的所共有的元素(获取交集并返回给当前集合)
coll1.add("XP");
coll1.add(false);
System.out.println(coll.retainAll(coll1));//true
System.out.println(coll);//[XP, false]
//equals(Object obj): 判断两个集合的元素是否相同
Collection coll2 = new ArrayList();
coll2.add("XP");
coll2.add(false);
System.out.println(coll);//[XP, false]
System.out.println(coll2);//[XP, false]
System.out.println(coll.equals(coll2));//true 因为利用的是ArrayList();是有序的,所以交换元素顺序会影响判断结果
}
hasCode,toArray
public void test4(){
Collection coll = new ArrayList();
coll.add("XP");
coll.add(false);
coll.add(123);
coll.add(456);
coll.add(new Person("小明", 21));
//hasCode() 返回当前对象的哈希值
System.out.println(coll.hashCode());//-1172761429
//toArray() 将集合转化为数组
Object[] arr = coll.toArray();
System.out.println(Arrays.toString(arr));//[XP, false, 123, 456, Person{name='小明', age=21}]
//拓展:调用Arrays的静态方法:asList() 数组--->集合
List list = Arrays.asList(new String[]{"AA", "bb"});
System.out.println(list);//[AA, bb]
List arr1 = Arrays.asList(new int[]{123,456,789});//写成这样会默认认为是一个元素
System.out.println(arr1);//[[I@ba8a1dc]
System.out.println(arr1.size());//1
List arr2 = Arrays.asList(new Integer[]{123,456,789});
System.out.println(arr2);//[123, 456, 789]
System.out.println(arr2.size());//3
//iterator(): 返回iterator接口的实例,用于遍历集合元素,放在IteratorTest.java中测试
}
迭代器Iterator接口遍历集合元素
- 遍历
public void test1(){
Collection coll = new ArrayList();
coll.add("XP");
coll.add(false);
coll.add(123);
coll.add(456);
coll.add(new Person("小明", 21));
Iterator iterator = coll.iterator();
//方式三:推荐 调用hasNext()判断是否还有元素
// hasNext()判断是否还有下一元素
while (iterator.hasNext()){
//next()指针下移,将下移后集合位置上的元素返回
System.out.println(iterator.next());
}
}
-
移除迭代器指向元素的操作
public void test2(){ Collection coll = new ArrayList(); coll.add("XP"); coll.add(false); coll.add(123); coll.add(456); coll.add(new Person("小明", 21)); Iterator iterator = coll.iterator(); while (iterator.hasNext()){ Object o = iterator.next(); if(o.equals("XP")){ iterator.remove(); } } Iterator iterator1 = coll.iterator(); while (iterator1.hasNext()){ System.out.print(iterator1.next()+"t"); //false 123 456 Person{name='小明', age=21} } } -
使用(JDK5新特性)foreach循环遍历集合(内部仍然调用迭代器)
public void test3(){ Collection coll = new ArrayList(); coll.add("XP"); coll.add(false); coll.add(123); coll.add(456); coll.add(new Person("小明", 21)); //for(集合中元素的类型:集合对象)相当于把coll的元素赋值给obj,改变obj中的元素不会改变原有集合中的元素 for(Object obj:coll){ System.out.print(obj+"t"); //XP false 123 456 Person{name='小明', age=21} } }
-
ArrayList、linkedList、Vector不同点
-
ArrayList:作为List接口的主要实现类,执行效率高(线程不安全),底层使用Object[] elementData存储
-
linkedList:底层使用双向链表存储,对于频繁的插入、删除操作,使用此类效率比ArrayList高
-
Vector:作为List接口的古老实现类,执行效率低(线程安全),底层使用Object[] elementData存储
-
-
相同点:三个类都实现了List接口,存储数据的特点相同,存储有序的可重复的数据
-
总结:
-
增:add(Object ele)
-
删:remove(int index)
-
改:sublist(int fromIndex,int toIndex)
-
查:get(int index)
-
插:add(int index,Object ele)
-
长度:size()
-
遍历:
-
Iterator
-
增强for循环
-
-
-
add,addAll,get
public void test1(){
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
list.add(new Person("小华",22));
list.add(456);//支持重复元素
System.out.println(list);//[123, 456, AA, Person{name='小华', age=22}, 456]
//void add(int index,Object ele) 在index位置插入ele元素
list.add(1,"BB");
System.out.println(list);//[123, BB, 456, AA, Person{name='小华', age=22}, 456]
//boolean addAll(int index,Collection eles):从index开始将eles中的所有元素插入
List list1 = Arrays.asList(1, 2, 3);
System.out.println(list.size());//6
System.out.println(list.addAll(list1));//true 默认加到最后
// 若不慎写成add,则会将list1看成一个元素加进去
System.out.println(list.size());//9
System.out.println(list);//[123, BB, 456, AA, Person{name='小华', age=22}, 456, 1, 2, 3]
//Object get(int index): 获取指定index位置的元素
System.out.println(list.get(2));//456
}
- indexOf,lastIndexOf,remove,set,sublist
public void test2(){
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
list.add(new Person("小华",22));
list.add(456);//支持重复元素
//int indexOf(Object obj) 返回obj在集合中首次出现的位置
int index = list.indexOf(456);
System.out.println(index);//返回所在位置1
System.out.println(list.indexOf(23311321));//不存在返回-1
//int lastIndexOf(Object obj) 返回obj在集合中最后出现的位置
System.out.println(list.lastIndexOf(456));//4
//Object remove(int index):移除指定index位置的元素,并返回此元素
Object o = list.remove(0);
System.out.println(o);//123
System.out.println(list);//[456, AA, Person{name='小华', age=22}, 456]
//Object set(int index,Object ele):修改指定index位置的元素为ele,并返回该元素
Object o1 = list.set(1, "cc");
System.out.println(o1);//AA
System.out.println(list);//[456, cc, Person{name='小华', age=22}, 456]
//List sublist(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的子集合,左闭右开,不会对原来的list造成影响
List subList = list.subList(0, 2);
System.out.println(list);//[456, cc, Person{name='小华', age=22}, 456]
System.out.println(subList);//[456, cc]
}
-
遍历的方法
public void test3(){ ArrayList list = new ArrayList(); list.add(123); list.add(456); list.add("AA"); //方式1 Iterator iterator = list.iterator(); while (iterator.hasNext()){ System.out.print(iterator.next()+"t");//123 456 AA } System.out.println(); //方式2 for (Object o:list){ System.out.print(o + "t");//123 456 AA } System.out.println(); //方式3 for (int i = 0; i < list.size(); i++) { System.out.print(list.get(i)+"t");//123 456 AA } }
-
实现类的对比
-
HashSet:作为Set接口的主要实现类:线程不安全的;可以存储null值
-
linkedHashSet:作为HashSet类的子类:遍历其内部数据时。可以按照添加的顺序遍历
-
TreeSet:可以按照添加对象的指定属性进行排序
-
-
要求:
- 向Set中添加的数据,其所在的类一定要重写hasCode与equals方法
- 重写的hasCode与equals尽可能保持一致性
- 不等于随机性
- 存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的
-
保证添加的元素按照equals()方法判断时不能返回true,即相同元素只能添加一个
-
示例:
public void test1() { HashSet set = new HashSet(); set.add(456); set.add(123); set.add("aa"); set.add("cc"); set.add(new Person("小花",18)); set.add(new Person("小花",18)); set.add(123); Iterator iterator = set.iterator(); while(iterator.hasNext()){ System.out.print(iterator.next()+"t");// } //没有重写hasCode与equals时的结果,两个Person对象都出现,而两个123却只出现一次 //aa cc Person{name='小花', age=18} 456 Person{name='小花', age=18} 123 //重写hasCode与equals时的结果,两个Person对象只有一个 //Person equals()…… //aa cc 456 Person{name='小花', age=18} 123 }
-
我们向HashSet中添加元素a,首先调用元素a所在类型的hashCode()方法,计算元素a的哈希值
-
此哈希值通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置),判断数组此位置上是否已经有元素
-
如果此位置上没有其他元素,则元素a添加成功—情况一
-
如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值,
-
如果不相同,则元素a添加成功------情况二
-
如果相同,调用元素a所在类的equals()方法,如果返回true,元素a添加失败,若返回false,则元素a添加成功--------情况三
-
ps:对于情况二和情况三而言,元素a与已经存在指定索引位置上的数据以链表的方式存储
- jdk7:元素a放到数组中,指向原来的元 素
- jdk8:原来的元素放在数组中,指向元素a(七上八下)
- 额外提供了双向链表,可以按照添加的顺序输出。
public void test2() {
linkedHashSet set = new linkedHashSet();
set.add(456);
set.add(123);
set.add("aa");
set.add("cc");
set.add(new Person("小花",18));
set.add(new Person("小花",18));
set.add(123);
System.out.println(set);
//额外提供了双向链表,可以按照添加的顺序输出,但是还是无序性,因为无序性指的是添加时的地址的无序性
//[456, 123, aa, cc, Person{name='小花', age=18}]
}
- 优点:对于频繁的遍历操作,效率较高
- 向TreeSet中添加的数据,要求是相同类的对象
- 两种排序方式:自然排序(实现Comparable接口)和定制排序(实现Compartor)
- 自然排序中,比较两个对象相同的标准为:compareTo()返回0,不再用equals()方法去判断
- 定制排序中,比较两个对象相同的标准为:compare()返回0,不再用equals()方法去判断
-
自然排序例子:
public void test1(){ TreeSet set = new TreeSet(); set.add(34); set.add(-34); set.add(44); set.add(11); set.add(8); Iterator iterator = set.iterator(); while(iterator.hasNext()){ System.out.print(iterator.next()+" "); }//-34 8 11 34 44 从小到大排序输出了 } public void test2(){ TreeSet set = new TreeSet(); set.add(new Person("Ming",20)); set.add(new Person("XiaoHu",24)); set.add(new Person("Wei",18)); set.add(new Person("Gala",21)); set.add(new Person("Ming",25)); Iterator iterator = set.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } //只按照姓名从小到大排列时: //Person{name='Gala', age=21} //Person{name='Wei', age=18} //Person{name='XiaoHu', age=24} //Person{name='XiaoMing', age=20} //没有出现另一个Ming,TreeSet的判断是否相同是按照CompareTo的返回值判断的 //修改之后考虑年龄的结果: //Person{name='Gala', age=21} //Person{name='Ming', age=20} //Person{name='Ming', age=25} //Person{name='Wei', age=18} //Person{name='XiaoHu', age=24} -
定制排序
public void test3(){ Comparator comparator = 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; return Integer.compare(p1.getAge(),p2.getAge()); }else { throw new RuntimeException("输入的类型不匹配"); } } }; TreeSet set = new TreeSet(comparator); set.add(new Person("Ming",20)); set.add(new Person("XiaoHu",24)); set.add(new Person("Wei",18)); set.add(new Person("Gala",21)); set.add(new Person("Ming",25)); Iterator iterator = set.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); }
注:Person类如下:
public class Person implements Comparable{
private String name;
private int age;
public Person() {
}
public Person(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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
System.out.println("Person equals()……");
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (age != person.age) return false;
return name != null ? name.equals(person.name) : person.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
//按照姓名从小到大排列,年龄从小到大排列
@Override
public int compareTo(Object o) {
if(o instanceof Person) {
Person person = (Person)o ;
int compare = this.name.compareTo(person.name);
if(0 != compare){
return compare;
}else {
return Integer.compare(this.age,person.age);
}
}else {
throw new RuntimeException("输入类型不匹配");
}
}
}
-
在List内取出重复数字值,要求尽量简单
思路:利用set的不可重复性
public void exercise1(){ List list = new ArrayList(); list.add(1); list.add(2); list.add(2); list.add(4); list.add(4); System.out.println(list);//[1, 2, 2, 4, 4] HashSet set = new HashSet(); set.addAll(list); List list1 = new ArrayList(set); System.out.println(list1);//[1, 2, 4] } -
Person类中重写了hashCode()和equals()方法,问下面程序输出为什么?
public void exercise2(){ HashSet set = new HashSet(); Person p1 = new Person("AA",1001); Person p2 = new Person("BB",1002); set.add(p1); set.add(p2); p1.setName("CC"); set.remove(p1); System.out.println(set);// set.add(new Person("CC",1001)); System.out.println(set);// set.add(new Person("AA",1001)); System.out.println(set);// }**
**
**
**
**
结果为:
[Person{name=‘CC’, age=1001}, Person{name=‘BB’, age=1002}]
[Person{name=‘CC’, age=1001}, Person{name=‘CC’, age=1001}, Person{name=‘BB’, age=1002}]
[Person{name=‘CC’, age=1001}, Person{name=‘CC’, age=1001}, Person{name=‘AA’, age=1001}, Person{name=‘BB’, age=1002}]
解析:
-
第一次添加时,是利用name=‘AA’, age=1001与name=‘BB’, age=1002计算的哈希值例如111,222,并放在了创造的数组里 假设为3号位置和11号位置
-
p1.setName(“CC”);后,p1,p2的位置并未发生改变,只是p1中的name属性改变了
set.remove(p1),寻找哈希值是利用此时的CC计算的哈希值,假设为333,所计算的位置为空,所以没有将原来的p1移除,第一次输出为上述第一次的答案
-
set.add(new Person(“CC”,1001));时,设此元素为p3,利用CC计算哈希值,假设为333,利用333计算得到到一个索引值,假设为13号位置,将其放入
-
set.add(new Person(“AA”,1001));时,设此元素为p4,利用AA计算哈希值,为111,利用111计算得到到一个索引值,3号位置,由于已存在元素,则调用equals方法判断是否相同,由于此时p1中的name属性以变为CC,所以判断p1,p4不相等,以链表方式存储,最终结果输出就有四个元素
-
-
Map接口:双列数据,保存有映射关系“key-value对”的集合(映射 )
------HashMap:作为Map的主要实现类,线程不安全,效率高,存储null的key和value
------linkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历
原因:在原有的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个元素,对于频繁的遍历操作,此类执行效率高于HashMap
------TreeMap:保证按照添加的key-value对进行排序,实现排序遍历,按照key来排序
底层使用的红黑树
------Hashtable:作为古老的实现类,线程安全,效率低,不能存储null的key和value
------Properties:常用来处理配置文件。key-value都是String类型
public void test1(){ HashMap map = new HashMap(); map.put(null,123);//不会报错 Hashtable hashtable = new Hashtable(); hashtable.put(null,123);//会抛出NullPointerException异常 } -
HashMap的底层原理
数组+链表(jdk7及之前)
数组+链表+红黑树(jdk8)
-
对Map结构的理解
Map中的key:无序的、不可重复的,使用Set存储所有的key-----要求key所在的类要重写equals和hashCode()(以HashCode)为例
value:无序的,可重复的,使用Collection存储所有的value----要求value所在的类要重写equals方法
一个键值对:key-value构成了一个Entry对象
entry:无序的、不可重复的,使用Set存储所有的entry
-
HashMap的底层实现原理,以jdk7 为例HashMap map = new HashMap();
在实例化以后,底层创建了长度是16的一维数组Entry[] table
可能已经执行过多次put
map.put(key1,value1):
首先,调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到Entry数组中的存放位置。
- 如果此位置上的数据为空,此时的key1-value1添加成功—情况一
- 如果此位置上的数据不为空(意味这此位置上存在一个或多个数据(以链表形式存在)),比较key1和已经存在的一个或多个数据的哈希值:
- 如果key1的哈希值与已经存在的数组的哈希值都不相同,此时可以添加成功—情况二
- 如果key1的哈希值和已经存在的某一个哈希值相同,继续比较调用key1所在类的equals方法进行比较
- 如果equals返回false,此时key1-value1添加成功—情况三
- 如果equals返回true使用value1替换原来的value
ps:对于情况二和情况三而言,元素a与已经存在指定索引位置上的数据以链表的方式存储
-
HashMap的底层实现原理,jdk8相较于jdk7的不同
-
new HashMap();底层没有创建一个长度为16的数组
-
jdk 8底层的数组是:Node[],而非Entry[]
-
首次调用put()方法时,底层创建长度为16的数组
-
jdk7 底层结构只有数组+链表,jdk8中的底层结构为数组+链表+红黑树
当数组的某一个索引位置上的元素以链表形式存在的数据个数>8,且当前数组的长度>64时,此时此索引位置上的所有数据改为使用红黑树存储
-
public void test3(){
//put()添加或修改
HashMap map = new HashMap();
map.put("AA",123);//添加
map.put("BB",1234);//添加
map.put("AA",114514);//修改
System.out.println(map);//{AA=114514, BB=1234}
//putAll():将map1中的元素添加或修改到map中去
HashMap map1 = new HashMap();
map1.put("CC",12322);
map1.put("DD",114514);
map1.put("BB",1313);
map.putAll(map1);
System.out.println(map);//{AA=114514, BB=1313, CC=12322, DD=114514}
//remove(Object key):以key为关键字移除某一元素,返回key对应的value,不存在返回null
Object ccValue = map.remove("CC");
Object value = map.remove("CCvcasd");
System.out.println(ccValue);//12322
System.out.println(value);//null
System.out.println(map);//{AA=114514, BB=1313, DD=114514}
//clear():清除所有元素
map.clear();
System.out.println(map.size());//0
System.out.println(map);//{}
}
查询
public void test4(){
HashMap map = new HashMap();
map.put("AA",123);//添加
map.put("BB",1234);//添加
//get(Object key)返回key对应的value,不存在返回null
System.out.println(map.get("AA"));//123
System.out.println(map.get("AAA"));//null
//containKey(Object key):是否包含指定的key
boolean containsAA = map.containsKey("AA");
boolean containsAAA = map.containsKey("AAA");
System.out.println(containsAA);//true
System.out.println(containsAAA);//false
//containValue(Object value):是否包含指定的value
boolean aa = map.containsValue(123);
boolean bb = map.containsValue(1233);
System.out.println(aa);//true
System.out.println(bb);//false
//size():判断map中键值对个数
System.out.println(map.size());//2
//equals(Object obj):判断当前map和参数对象obj是否相等
HashMap map1 = new HashMap();
map1.put("AA",123);//添加
map1.put("BB",1234);//添加
System.out.println(map.equals(map1));//true
//isEmpty(),判断是否为空
map.clear();
System.out.println(map.size());//0
System.out.println(map.isEmpty());//true
}
元视图操作方法(遍历)
public void test5(){
HashMap map = new HashMap();
map.put("AA",123);//添加
map.put("BB",1234);//添加
map.put("CC",114514);//添加
//遍历所有的key集
//keySet()返回所有的key构成的Set集合
Set set = map.keySet();
for(Object key:set){
System.out.print(key + " ");
}//AA BB CC
System.out.println();
//遍历所有的value集合
//values()返回所有的value构成的Collection集合
Collection value = map.values();
Iterator iterator = value.iterator();
while (iterator.hasNext()){
System.out.print(iterator.next()+" ");
}//123 1234 114514
System.out.println();
//遍历所有的key-value集合
//方式一: entrySet();返回所有entry构成的Set集合
for (Object obj : map.entrySet()) {
System.out.print(obj + " ");
}//AA=123 BB=1234 CC=114514
System.out.println();
for (Object obj : map.entrySet()) {
Map.Entry entry = (Map.Entry) obj;
System.out.print(entry.getKey() + "----->" + entry.getValue() + " ");
}//AA----->123BB----->1234CC----->114514
System.out.println();
//方式二:利用之前的方法自己写
Set keySet = map.keySet();
Iterator iterator1 = keySet.iterator();
while(iterator1.hasNext()){
Object keyNext = iterator1.next();
Object valueNext = map.get(keyNext);
System.out.print(keyNext + ">>>>" +valueNext+" ");
}//AA>>>>123 BB>>>>1234 CC>>>>114514
}
利用TreeMap排序
-
自然排序
public void test1(){//自然排序 TreeMap treeMap = new TreeMap(); Person p1 = new Person("Ming",21); Person p2 = new Person("Wei",18); Person p3 = new Person("XiaoHu",25); Person p4 = new Person("Gala",19); Person p5 = new Person("Cryin",21); treeMap.put(p1,"辅助"); treeMap.put(p2,"打野"); treeMap.put(p3,"上单"); treeMap.put(p4,"AD"); treeMap.put(p5,"中单"); //自然排序 for (Object obj : treeMap.entrySet()) { Map.Entry entry = (Map.Entry) obj; System.out.println(entry.getKey() + " >> " + entry.getValue()); } } -
定制排序
public void test2(){//定制排序(年龄由大到小) TreeMap treeMap = new TreeMap(new Comparator() { @Override public int compare(Object o, Object t1) { if(o instanceof Person && t1 instanceof Person){ Person pp1 = (Person) o; Person pp2 = (Person) t1; return Integer.compare(pp1.getAge(),pp2.getAge()); }else { throw new RuntimeException("输入数据类型不匹配"); } } }); Person p1 = new Person("Ming",22); Person p2 = new Person("Wei",18); Person p3 = new Person("XiaoHu",25); Person p4 = new Person("Gala",19); Person p5 = new Person("Cryin",21); treeMap.put(p1,"辅助"); treeMap.put(p2,"打野"); treeMap.put(p3,"上单"); treeMap.put(p4,"AD"); treeMap.put(p5,"中单"); for (Object obj : treeMap.entrySet()) { Map.Entry entry = (Map.Entry) obj; System.out.println(entry.getKey() + " >> " + entry.getValue()); } }
-
在工程文件下新建
-
对中文操作需要勾上如下图所示的位置
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
public class PropertiesTest {
public static void main(String[] args) {
Properties pros = new Properties();
FileInputStream file = null;
try {
file = new FileInputStream("集合/jdbc.properties");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
pros.load(file);//加载对应的文件
} catch (IOException e) {
e.printStackTrace();
}
String name = pros.getProperty("name");
String password = pros.getProperty("password");
System.out.println("name = "+name+", password = "+password);
//name = 翔, password = abc123
try {
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Collections工具类
-
定义:操作Collection和Map的工具类
-
Collection和Collections的区别
Collection是接口, Collections是工具类
public void test1(){
ArrayList list = new ArrayList();
list.add(456);
list.add(123);
list.add(733);
list.add(114514);
System.out.println(list);//[456, 123, 733, 114514]
//reverse(List) 反转List元素的顺序
Collections.reverse(list);
System.out.println(list);//[114514, 733, 456, 123]
//shuffle(list)对List集合元素进行随机排序
Collections.shuffle(list);
System.out.println(list);
//第一次运行:[114514, 123, 733, 456]
//第二次运行:[114514, 123, 456, 733]
//sort(List) 自然排序 sort(list,Comparator) 定制排序
Collections.sort(list, new Comparator
-
解决线程安全问题的方法
public void test2(){ ArrayList list = new ArrayList(); list.add(456); list.add(123); list.add(733); list.add(114514); System.out.println(list);//[456, 123, 733, 114514] //Collections.synchronizedXXX() 方法,返回的集合为线程安全的 List list1 = Collections.synchronizedList(list);//返回的list1即为线程安全的 }



