数组特点:
一组数据类型相同的元素集合
创建数组时,必须给定长度,而且一旦创建长度不能改变,
一旦数组装满元素,需要创建一个新的数组,将元素复制过去
不方便:判断
单列集合:
一次放进去一个值(对象)
Collection:定义单列集合共有放法
List:可以有重复元素
ArraysList:数组列表
底层有一个数组,可以动态扩展数组长度,并提供一系列方法操作
查询快
中间增加,删除慢
add(E,e)默认向末尾添加元素
arrayList.add("a");
arrayList.add(1,"b");
arrayList.remove("a");
// System.out.println(arrayList.remove("x"));根据内容删除匹配的第一个元素,删除成功返回true,否则返回false
//System.out.println(arrayList.remove(1));删除并返回指定位置元素
//System.out.println(arrayList.get(1));获取指定位置上的元素
System.out.println(arrayList.indexOf("d"));
//System.out.println(arrayList.lastIndexOf("d"));
//System.out.println(arrayList.set(2,"x"));替换并返回指定位置上的元素
arrayList.clear();
System.out.println(arrayList.isEmpty());
}
arrayList遍历:
1.增强for循环
for(String s:arrayList){
System.out.println(s);
}
2.普通for循环(可以修改数组)
for(int i=0;i< arrayList.size();i++){
if("a".equals(arrayList.get(i))){
arrayList.remove(i);
}
}
使用迭代器遍历数组
ArrayList<String> arrayList=new ArrayList();
arrayList.add("a");
arrayList.add("a");
arrayList.add("a");
arrayList.add("a");
arrayList.add("a");
Iterator<String> it=arrayList.iterator();
while(it.hasNext()){
String s=it.next();
if(s.equals("a")){
it.remove();
}
LinkeList:链表列表
底层是一个链表结构
查询慢
增加,删除快
LinkedList<String> linkedList=new LinkedList();
linkedList.add("a");
linkedList.add("b");
linkedList.add("c");
linkedList.add("d");
linkedList.add("e");
linkedList.add("f");
linkedList.add(1,"x");
System.out.println(linkedList);
linkedList.removeFirst();
System.out.println(linkedList);
System.out.println(linkedList.get(1));
linkedList.clear();
System.out.println(linkedList);
迭代器遍历链表
ListIterator<String> iterator= arrayList.listIterator(arrayList.size());
while (iterator.hasPrevious()){
System.out.println(iterator.previous());
}*/
set
创建一个compareto接口的匿名内部类对象
ArrayList<Integer> list=new ArrayList<>();
Collections.addAll(list,1,2,4,5,3);
Collections.sort(list, new Comparator<Integer>() {//创建一个compareto接口的匿名内部类对象,就是省去一个创建类,简化语法
@Override
public int compare(Integer o1, Integer o2) {
return o2.intValue()-o1.intValue();
}
});
//Collections.sort(list);
System.out.println(list);
System.out.println(Collections.binarySearch(list, 1));
treeset:
不能存储重复元素的
可以根据值进行排序,底层使用了树形结构,树结构本身就是有序的,
向树形结构中添加元素是,如何判断元素大小以及元素是否重复
向TreeSet中添加的元素类型必须实现Compare接口,重写compareTo(),
每次添加元素时,调用compareTo进行元素大小判断(小于0放左子节点,等于0表示重复,大于0放在右子节点)
TreeSet<Integer> tree=new TreeSet<>();
tree.add(1);
tree.add(5);
tree.add(4);
tree.add(2);
tree.add(1);
tree.add(3);
System.out.println(tree);
TreeSet<student> treeSet=new TreeSet<>();
// student str1=new student("张三",100);
student str2=new student("李四",101);
student str3=new student("王五",102);
student str4=new student("张三",100);
student str5=new student("李三",105);
treeSet.add(new student("张三",100));
treeSet.add(str2);
treeSet.add(str3);
treeSet.add(str4);
treeSet.add(str5);
System.out.println(treeSet);
hashset
会按照hashcode排序
HashSet<student> hashSet=new HashSet<>();
hashSet.add(new student("张三",100));
hashSet.add(new student("李四",101));
hashSet.add(new student("王五",102));
hashSet.add(new student("张柳",103));
hashSet.add(new student("张三",100));
System.out.println(hashSet);
双列集合:
键 值
Map接口共性
数据存储是键,值是形式存储
键不能重复的,值是可以重复
通过键可以找到值
一个键只能映射一个值
HashMap
键是无序的
HashMap<String,Integer> hashMap=new HashMap<>();
hashMap.put("d",10);
hashMap.put("b",101);
hashMap.put("c",102);
hashMap.put("a",10);
hashMap.put("a",102);
System.out.println(hashMap);
//hashMap.clear();
System.out.println(hashMap.containsKey("c"));
System.out.println(hashMap.remove("a"));
System.out.println(hashMap.isEmpty());
1.底层使用一个长度默认为16的数组,用来确定元素的位置,每次用key计算出哈希值,用哈希值%数组长度确定元素位置,将元素放在哈希表中指定位置,
2.后来继续添加元素,如果出现相同位置且不重复的元素,那么后来的元素添加到之前元素的next节点
3.当连表长度等于8时,且哈希数组长度大于64链表才会转为红黑树
4.哈希表负载因子为0.75,当哈希表使用数组0.75时,会自动扩容为原来数组长的2倍。
hashtable
Hashtable
底层实现也是用到key的哈希值,计算位置,判断元素是否重复
方法上都添加了synchronized锁
Hashtable中不能存储为NULL的键和为NULL的值
HashMap可以存储一个为NULl键,值可以为null.
Hashtable<String,String> hashtable=new Hashtable<>();
hashtable.put("ad","ad");
hashtable.put("ad","ad");
hashtable.put("d","d");
hashtable.put("a","a");
hashtable.put("aad","aad");
System.out.println(hashtable);
treemap
/*
TreeMap
顶层使用树形结构存储键值
键可以排序
键元素类型必须实现Comparable接口,重写compareTo()方法
*/
public static void main(String[] args) {
TreeMap<Integer,String> treeMap=new TreeMap<>();
treeMap.put(1,"aa");
treeMap.put(2,"ab");
treeMap.put(1,"aaa");
treeMap.put(4,"ba");
treeMap.put(5,"aca");
System.out.println(treeMap);
/* treeMap.ceilingKey(1);
treeMap.isEmpty();
treeMap.size();
treeMap.get(1);*/
//map遍历
//方法1:先拿到所有的键 遍历键 根据键找值
Set<Integer> keySet=treeMap.keySet();
for(Integer key:keySet){
System.out.println(key+":"+treeMap.get(key));
}
//方法二:推荐遍历方法
Set<Map.Entry<Integer,String>> entries=treeMap.entrySet();
for(Map.Entry entry:entries){
System.out.println(entry.getKey()+":"+entry.getValue());
}
}
泛型
什么是泛型?
● 泛型,即“参数化类型” 。一提到参数,最熟悉的就是定义方法时有形 参,然后调用此方法时传递实参。
● 参数化类型,就是将类型由原来的具体的类型参数化,类似于方法中的 变量参数,此时类型也定义成参数形式,然后在使用/调用时传入具体的 类型。
● Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编 译时类型安全检测机制,泛型的好处就是在编译的时候能够检查类型安 全。
泛型类
泛型类型用于类的定义中,被称为泛型类。通过泛型可以完成对一组类的操作对外开 放相同的接口。
一个最普通的泛型类: public class Demo{ / /T可以为任意标识符,常见的如T、E、K、V等形式的参数常用于表示泛型 private T key; / /key这个成员变量的类型为T,T的类型由外部指定 public Demo(T key) { / /泛型构造方法形参key的类型也为T,T的类型由外部指定 this.key = key; } public T getKey(){ / /泛型方法getKey的返回值类型为T,T的类型由外部指定 return key; } }
传入的实参类型需与泛型的类型参数类型相同,即为Integer. Demo demo = new Demo(123456);
1.泛型的类型参数只能是类类型
2.泛型的类型参数可以有多个。
3.如果没有定义具体类型,默认为Object
从泛型类派生子类
子类也是泛型类,子类和父类的泛型类型要一致 class A extends Demo 子类不是泛型类,
父类要明确泛型的数据类型 class A extends Demo
泛型接口
泛型接口与泛型类的定义及使用基本相同。
public interface Demo { //定义一个泛型接口 } 子类也是泛型类,
子类和父类的泛型类型要一致 class A implements Demo{ } 子类不是泛型类,
父类要明确泛型的数据类型 public class A implements Demo { }