概述
- 在之前的学习中遇到多个变量,我们是使用数组进行存储
- 数组在创建的时候就需要指定长度
- 由于数组的长度不可以变,不可以新增,数组在扩容/缩容的时候需要创建一个新的数组
- 集合概念和数组类似,也是可以存储多个引用变量
- 集合的长度是可以变的
- 集合还提供了格式排序,比较等等方法,方便用户对集合的操作
- 集合本质上是数组的封装类,本质上最终存储数据还是数组
- 根据不同的数据结构,集合可以分为以下几类
- List
- Set
- Map
- List:线性有序的集合

2. Set:无序的集合

3. Map:使用key/value的方法进行存储
List有序集合
- List在java是一个接口, 它父类是Collection,它有各种不同的底层实现
- ArrayList
- LinkedList
- Vector
ArrayList的基本使用
集合的创建,新增,获取 和删除
ArrayList list = new ArrayList();//给集合中放入对象list.add(1); //0list.add("aa");//1list.add(true);//2list.add(new Student("小王",15));//获取数据Integer i = (Integer) list.get(0);String aa = (String) list.get(1);Boolean flag = (Boolean) list.get(2);Student student = (Student) list.get(3);list.remove(2);//删除System.out.println(i);System.out.println(aa);System.out.println(flag);System.out.println(student.toString());
集合的遍历
//第一种遍历集合的方式for (int j=0;j<list.size();j++){System.out.println(list.get(j));}//第二种遍历的方式System.out.println("第一个遍历的方式:");//类型 一个对象的变量 : 集合的遍历for (Object obj :list) {System.out.println(obj);}//第三种方式lambda表达式list.forEach(obj->{System.out.println(obj);});
泛型
List有三种中实现,都是继承的List接口只是在实现上不同,在使用上是一摸一样的
- LinkedList是通过链表,删除和新增的速度快查询慢
- ArrayList是查询快,删除和新增慢
- Vector都慢,但是线程安全
所以在使用的时候,都会直接使用List指向三种不同类型的集合
List list = new ArrayList();List linkedList = new LinkedList();
在list的add 和 get方法,是不需要设置类型的
- 在添加虽然可以放入不同的数据类型
- 但是在获取结果的时候需要强制类型转换,就会影响程序的速度
- 可以通过泛型解决这个问题
泛型指的是可以将集合中的数据定义成指定的类型,在获取结果的时候不需要强制类型转换
List<Integer> list = new ArrayList();//List linkedList = new LinkedList();list.add(1);//只能存放Integer类型//list.add("a");Integer i = list.get(0);//获取数据的不需要进行类型转换
泛型的定义
reverse实现集合的反转
- shuffle:随机重置
sort:可以进行排序
- 默认情况下是直接使用升序
- 如果需要使用降序,请重写Comparator接口
Collections.sort(list, new Comparator<Integer>() {//实现比较的规则@Overridepublic int compare(Integer o1, Integer o2) {if(o1>o2){return -1;}else if(o1<o2){return 1;}return 0;}});
binarySearch:使用二分查询,查找对应的值的下标
将一组对象,直接放入到集合中,默认情况下没有顺序概念,不能插入相同的元素
一般添加元素
//创建对象Book b1 = new Book("天龙八部","金庸",98);Book b2 = new Book("神雕侠侣","金庸",78);Book b3 = new Book("背影","朱自清",18);//创建集合Set<Book> set = new HashSet<>();//将对象放入到集合中set.add(b1);set.add(b2);set.add(b3);
遍历集合
//遍历集合查询//增强foreach/*for (Book book :set) {System.out.println(book.toString());}*///使用lambda表达式/*set.forEach(book -> {System.out.println(book.toString());});*///使用迭代器Iterator<Book> iterable = set.iterator();//循环迭代while(iterable.hasNext()){Book book = iterable.next();System.out.println(book.toString());}
三种实现
- HashSet:底层直接使用HashMap进行实现的,
- 在长度超过一定数量的时候,会进行数据重排
- 主要是通过hashCode定义元素的插入位置
- 在判断两个元素是否一致的时候,需要重写hashCode和equals两个方法
- LinkedHashSet:由于底层主要是通过链表实现的,没有扩容的问题,
- 会保证插入的顺序是不变的
- TreeSet:底层是通过tree实现的
- Collections的sort只对list有效,如果要使用排序则要使用TreeSet
- 插入的对象需要实现Comparable接口才行
- 在重写Comparable接口的时候,如果返回的结果是0,那么元素就不会被插入了
- HashSet:底层直接使用HashMap进行实现的,
equals和hashcode的区别
通过key将对应的值放入到集合中,在集合中主要是通过key定义元素的位置
Map map = new HashMap();//放入值map.put(1,"小明");//获取值Object result = map.get(1);System.out.println("result="+result);map.put("a","小明");map.put("a","小黑");Object rs = map.get("a");System.out.println("a的值:"+rs);
HashMap存储的最小的单位是一个Entry(其中包括了key和Value)
public static void main(String[] args) {Map<Integer, Student> map = new HashMap<>();for(int i=0;i<5;i++){map.put(i,new Student("学生"+i,1+i));}//第一种,通过EntrySet遍历//获取map中所有的entrySet<Map.Entry<Integer,Student>> entrySet = map.entrySet();//遍历存储了所有的entry的Setfor (Map.Entry<Integer, Student> entry :map.entrySet()) {//获取Entry的key值Integer key = entry.getKey();//获取Entry具体存储的值Student s = entry.getValue();System.out.println(key+":"+s.getName());}//第二种通过遍历keySet获取值for (Integer key : map.keySet()) {//通过key获取值Student value = map.get(key);System.out.println(key+":"+value.getName());}//第三种使用lambda表达式map.forEach((key,value)->{System.out.println(key+":"+value.getName());});}
Map的实现
- HashMap:基本实现,使用key-value形式对数据进行存储,并且是在Hashtable的基础上进行了优化,速度很快,但是线程不安全,需要使用ConcurrentHashMap保证线程的安全
TreeMap:可以对key值进行排序
- 所以key的类需要实现Comparable
```java
public class MyKey implements Comparable
{ String key;
public MyKey(String key) { this.key = key; }
public String getKey() { return key; }
public void setKey(String key) { this.key = key; }
@Override public int compareTo(MyKey o) { Integer keyValue = Integer.parseInt(o.getKey());
return Integer.parseInt(this.key)-keyValue; }
@Override public String toString() { return “MyKey{“ +
"key='" + key + '\'' +'}';
} } ```
- 所以key的类需要实现Comparable
```java
public class MyKey implements Comparable
Properties也是map的实现,可以直接从文本文件中通过key读取其相关的值
创建一个properties文件,以key=value的形式存储数据
name=小明password=123
通过代码加载文件,读取数据
Properties ps = new Properties();//加载properties的文件ps.load(TestMap004.class.getResourceAsStream("info.properties"));//通过key将properties文件中的值进行获取String name = ps.getProperty("name");String pwd = ps.getProperty("password");System.out.println(name+":"+pwd);
