Java集合概述
Java集合类存放于java.util包中,是一个用来存放对象的容器
集合只能存放对象。比如你存一个int类型数据1放入集合中,其实它是自动转换成Integer类后存入的,java中的每一种基本类型都有对应的引用类型。
集合存放是多个对象的引用,对象本身还是放在堆内存中
集合可以存放不同类型,不限数量的数据类型
Java集合可分为Set,List和Map三种大体系
Set:无序,不可重复的集合
List:有序,可重复的集合
Map:具有映射关系的集合
HashSet集合
HashSet是Set接口的典型实现,大多数时候使用Set集合时都使用这个实现类。我们大多数时候说的set集合指的都是HashSet
HashSet按Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。
HashSet具有以下特点:
不能保证元素的排列顺序
不可重复(HashCode不相等)
HashSet不是线性安全的
集合元素可以使null
当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据hashCode值决定该对象在HashSet中的存储位置
(存在Set集合中的哪个位置由这个值的hashCode决定)
如果两个元素的equals()方法返回true,但他们的hashCode()返回值不相等,hashSet将会把他们存放在不同的位置,但依然可以添加成功。
Set set=new HashSet(); //可存放所有类型的对象
set.add(1);//添加元素
set.add("a");
System.out.println(set);
set.remove(1); //移出元素
System.out.println(set);
System.out.println(set.contains("a")); //判断是否包含元素
set.clear(); //清空集合
System.out.println(set);
//使用迭代器遍历集合
Iterator it =set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//for each迭代集合,推荐使用
for(Object obj:set){
System.out.println(obj);
}
System.out.println(set.size());//获取集合的元素个数
//如果想要让集合只能存同样的类型的对象,怎么做?
//使用泛型
Set<String> set1=new HashSet<String>();
set1.add("abc");
HashSet集合判断两个元素相等的标准:两个对象通过equals()方法比较相等,并且两个对象的hashCode()方法返回值也相等
TreeSet集合
TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。
TreeSet支持两种排序方法:自然排序和定制排序,默认情况下,TreeSet采用自然排序
自然排序
Set<Integer> set=new TreeSet<Integer>();
set.add(5);
set.add(2);
set.add(4);
set.add(3);
System.out.println(set);
运行结果:
[2, 3, 4, 5]
TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后将集合元素按升序排序
必须放入同样类的对象否则可能会发生类型转换异常,我们可以使用泛型来进行限制
Person类
class Person implements Comparator<Person>{ //把Person对象存到TreeSet中并且按照年龄排序
int age;
String name;
public Person(){
}
public Person(int age, String name) {
// super();
this.age = age;
this.name = name;
}
@Override
public int compare(Person o1, Person o2) {
if(o1.age>o2.age){ //年龄正序排列
return 1;
}else if(o1.age<o2.age){
return -1;
}else{
return 0;
}
}
}
main方法
Person p1 =new Person(13,"张三");
Person p2 =new Person(15,"李四");
Person p3 =new Person(12,"王五");
Person p4 =new Person(17,"赵六");
Set<Person> set = new TreeSet<Person>(new Person());
set.add(p1);
set.add(p2);
set.add(p3);
set.add(p4);
for(Person p:set){
System.out.println(p.name+" "+p.age);
}
运行结果:
王五 12
张三 13
李四 15
赵六 17
List集合
List与ArrayList
List代表一个元素有序、且可重复的集合,集合中的每个元素都有其对应的顺序索引
List允许使用重复元素,可以通过索引来访问指定位置的集合元素。
List默认按元素的添加顺序设置元素的索引
List集合里添加了一些根据索引来操作集合元素的方法
public class Test5 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("b");//第一个,索引下标为0
list.add("d");//索引下标1
list.add("c");//索引下标2
list.add("a");//索引下标3
list.add("d");
System.out.println(list);
System.out.println(list.get(2));//通过索引来访问指定位置的集合元素
list.add(1,"f");//在指定索引下标的位置插入数据
System.out.println(list);
List<String> l = new ArrayList<String>();
l.add("123");
l.add("456");
list.addAll(2,l);//在指定索引下标的位置插入集合
System.out.println(list);
System.out.println(list.indexOf("d"));//获取指定元素在集合中第一次出现的索引下标位置
System.out.println(list.lastIndexOf("d"));//获取指定元素在指定集合中最后一次出现的索引位置
list.remove(2);//根据指定的索引下标移出元素
System.out.println(list);
list.set(1, "ff");
System.out.println(list);
//根据索引下标的起始位置截取一段元素形成一个新的集合,截取的时候,包含开始的索引,不包含结束的索引
List<String> sublist=list.subList(2, 4);
System.out.println(sublist);
System.out.println(list.size());//集合的长度
}
}
运行结果:
[b, d, c, a, d]
c
[b, f, d, c, a, d]
[b, f, 123, 456, d, c, a, d]
4
7
[b, f, 456, d, c, a, d]
[b, ff, 456, d, c, a, d]
[456, d]
7
Map集合
Map用于保存具有映射关系的数据,因此Map集合里保存着两组值,一组值用于保存Map里面的key,另一组用于保存Map里的value
Map中的key和value都可以是任何引用类型的数据
Map中的key不允许重复,即同一个Map对象的任何两个key通过equals方法比较中返回false
key和value之间存在单项一对一关系,即通过指定的key总能找到唯一的,确定的Value
public class Test6 {
public static void main(String[] args) {
Map<String,Integer> map=new HashMap<String, Integer>();
map.put("b", 1);//添加数据
map.put("c", 2);
map.put("e", 2);
System.out.println(map);
System.out.println(map.get("b"));//根据key取值
map.remove("c");//根据key来移出键值对
System.out.println(map);
System.out.println(map.size());//map集合的长度
System.out.println(map.containsKey("a"));//判断当前的map集合书否包含指定的key
System.out.println(map.containsValue(1));//判断当前的map集合书否包含指定的value
Set<String> keys=map.keySet();//获取map集合的key集合
map.values();//获取集合的所有value值
//遍历集合,通过map.keySet();
for(String key:keys){
System.out.println("kay:"+key+","+"value:"+map.get(key));
}
//通过map.entrySet();
Set<Entry <String,Integer>> entrys=map.entrySet();
for(Entry<String,Integer>en:entrys) {
System.out.println("kay:"+en.getKey()+","+"value:"+en.getValue());
}
}
}
运行结果:
{e=2, b=1, c=2}
1
{e=2, b=1}
2
false
true
kay:e,value:2
kay:b,value:1
kay:e,value:2
kay:b,value:1
TreeMap集合
TreeMap存储Key-Value对时,需要根据Key随key-value对进行排序。TreeMap可以保证所有的Key-Value对处于有序状态
TreeMap的Key的排序
自然排序:TreeMap的所有key必须实现Comparable接口,而且所有的Key应该是同一个类的对象,否则将会抛出ClassCastException
//TreeMap的自然排序是字典排序
Map<Integer,String> map=new TreeMap<Integer, String>();
map.put(4, "a");
map.put(2, "a");
map.put(3, "a");
map.put(1, "a");
System.out.println(map);
Map<String,String> map1=new TreeMap<String, String>();
map1.put("b", "b");
map1.put("c", "c");
map1.put("d", "d");
map1.put("a", "a");
map1.put("ab", "ab");
map1.put("1", "ab");
map1.put("10", "ab");
System.out.println(map1);