概述:
在之前的学习之前,我们都是使用数组进行储存.
数组在创建的时候就已经确定了长度.
由于数组的长度一经创建就被确定,所以增加删除数组内的元素时,需要创建一个新的数组来接收元素
集合和数组概念相似,也是用于储存多个引用变量的
集合的长度时可变的
集合还提供了排序,比较等方法,方便用户对集合进行操作
集合本质上是数组的封装类,最终存储数据还是数组
List有序集合
List是java中的一个接口,父类是Collection,它有各种不同的底层实现
ArrayList
LinkedList
Vector
ArrauList的基本使用
集合的创建,增加,获取和删除
ArrayList list = new ArrayList();
//给集合中放入对象
list.add(1); //0
list.add("aa");//1
list.add(true);//2
list.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());
集合的遍历
ArrayList list = new ArrayList();
//给集合中放入对象
list.add(1); //0
list.add("aa");//1
list.add(true);//2
list.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());
关于泛型
List有三种中实现,都继承了List接口只是在实现上不同,在使用上一模一样
LinkedList是通过链表,增加和删除速度快,查询速度慢
ArrayList是查询快,增加和删除慢
Vector是都慢,但是他线程安全
-
泛型指的是可以将集合中的数据定义成指定的类型,在获取结果的时候不需要强制类型转换
List<Integer> list = new ArrayList();
//List linkedList = new LinkedList();
list.add(1);//只能存放Integer类型
//list.add("a");
Integer i = list.get(0);//获取数据的不需要进行类型转换
-
泛型的定义
-
一个泛型参数定义
public class MyArrayListImpl<T> { public void add(T obj){ } public T get(int i){ return null; } }
-
多个泛型参数的定义
public class MyConvert<S,D> { public D to(S a){ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); return (D) simpleDateFormat.format(a); } }
Collections工具类
-
- reverse实现集合反转
shuffle随机重置
sort可以进行排序
默认情况下直接使用升序
如果需要使用降序,需要重写Comparator接口
Collections.sort(list, new Comparator<Integer>() {
//实现比较的规则
@Override
public int compare(Integer o1, Integer o2) {
if(o1>o2){
return -1;
}else if(o1<o2){
return 1;
}
return 0;
}
});
binarySearch:使用二分查询,查询相应的值的下标
必须是升序
查询的关键字
int result = Collections.binarySearch(list, new Student("学生" + 6, 13), (o1, o2) -> {
if(o1.getAge()>o2.getAge()){
return 1;
}else if(o1.getAge()<o2.getAge()){
return -1;
}
//两个值相同
return 0;
});
System.out.println("查询的结果是:"+result);
Set无序集合
将一组对象,直接放入集合中,默认情况下是没有顺序的,不能插入相同的元素
一般添加元素
//创建对象
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:底层时链表结构,所以没有扩容问题
会保证插入顺序是不变的
TerrSet:底层是通过Terr实现的
Collections的sort只对list有效,如果要使用排序则要使用TreeSet
插入的对象需要实现Comparable接口才行
在重写Comparable接口的时候,如果返回的结果是0,那么元素就不会被插入了
equals和hashcod的区别
equals主要是判断两个对象的值是否相等
hashcode是hash集合的位置,在hash集合中判断两个元素是否一致,主要通关hashcode判断
Map键值对集合
通过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中所有的entry
Set<Map.Entry<Integer,Student>> entrySet = map.entrySet();
//遍历存储了所有的entry的Set
for (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
public class MyKey implements Comparable<MyKey>{
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 + '\'' +
'}';
}
}
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);