集合
概念
集合也称容器,其提供了不同结构的集合类(链表、哈希、树实现的数组),在Java.util中;
单列集合
一次放进去一个值(对象);
collection接口,定义了单列集合共有的方法;
List
可以有重复元素;
ArrayList
数组列表,可动态扩展长度,并提供一系列方法;
查询快,加删慢;
LinkedList
链表列表;
查询慢,加删快;
Vector
数组列表,线程安全
set
不能有重复元素,是无序的,没有索引;
HashSet
treeSet
双列集合
键值;
HashMap
数据存储是按值的形式存储,键不能重复,但值可以,通过键可以找到值,一个键对应一个值
TreeMap
底层使用树结构,键可以排序,键元素类型必须实现Comparable接口,重写方法compareTo()
Hashtable
线程安全,其中方法都有synchronized锁
数组的弊端
每次装入元素时的,都要判满;
对数组进行增减操作时还需移动元素;
一组数据类型相同的元素集合;
创建数组时,必须给定长度,长度一旦给定不能修改;
一旦数组装满,需要创建一个新数组,将元素复制过去;
集合API
list接口和实现类
List接口下有ArrayList、LinkedList、Vector三类;
上述三类提供的方法功能大同小异,接下来会在代码中进行解释;
ArrayList
public class ArrayListDemo1 {
public static void main(String[] args) {
/*
集合容器中默认可以添加Object类型,
但是一般还是习惯一个集合对象中只保存同一种类型.
因为保存多个类型,后期处理时,涉及到类型的转换问题
泛型:可以在声明类型时,可以自定义参数类型
ArrayList<E>
add(E e) 默认是向末尾来添加元素
*/
ArrayList <String > arrayList=new ArrayList();
arrayList.add("a");
arrayList.add("b");
arrayList.add("b");
arrayList.add("b");
//arrayList.remove("a");根据类容散出匹配的第一个元素,删除成功返回true
//System.out.println(arrayList.remove(1));删除并返回指定位置元素
System.out.println(arrayList.get(1));//获取指定位置上的元素
System.out.println(arrayList.indexOf("b"));//返回第一次出现的位置
System.out.println(arrayList.lastIndexOf("b"));//返回最后一次出现的位置
System.out.println(arrayList.set(1,"x"));//替换并返回指定位置的元素
//arrayList.clear();清空集合中的元素
//System.out.println(arrayList.isEmpty());判断集合中的元素是否为空, 为空返回true
System.out.println(arrayList.contains("c"));//判断是否包含指定元素
System.out.println(arrayList.size());//返回元素的个数
System.out.println(arrayList);
}
}
List接口的迭代
public class ArrayListDemo2 {
public static void main(String[] args) {
ArrayList<String > arrayList=new ArrayList();
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("d");
/*
List接口实现类/ list集合遍历方式1:for循环
允许操作(删除)元素,注意索引的变化与元素位置的移动
*/
for (int i = 0; i < arrayList.size(); i++) {
if("a".equals(arrayList.get(i))){
arrayList.remove("a");
i--;
}
}
System.out.println(arrayList);
/*
List接口实现类/ list集合遍历方式2: 增强for循环
遍历元素时不允许删除集合元素(添加),只适合遍历
*/
for(String s:arrayList){
/*
if(s.equals("a")){
arrayList.remove(s);//增强for循环不允许删除元素
}*/
System.out.println(s);
}
/*
List接口实现类/ list集合遍历方式3: 使用迭代器遍历
*/
//获得集合对象的迭代对象
/* Iterator<String> it= arrayList.iterator();
while(it.hasNext()){
String s= it.next();//获取下一个元素
// System.out.println(s);
if(s.equals("a")){
it.remove();//使用迭代器删除元素
}
System.out.println(s);
}*/
// ListIterator 迭代器 只能对List接口下的实现类遍历
// 从前往后遍历
/* ListIterator<String> listIterator= arrayList.listIterator();
while(listIterator.hasNext()){
System.out.println(listIterator.next());
}*/
//从后往前遍历
ListIterator<String> listIterator= arrayList.listIterator(arrayList.size());
while(listIterator.hasPrevious()){
System.out.println(listIterator.previous());
}
}
}
LinkedList
public class LinkdelistDemo {
public static void main(String[] args) {
LinkedList<String > linkedList=new LinkedList<>();
linkedList.add("x");
linkedList.add("b");
linkedList.add("c");
linkedList.add("d");
linkedList.add("e");
linkedList.add("f");
//System.out.println(linkedList.get(2));//获取指定位置上的元素
//System.out.println(linkedList.remove("x"));//根据内容删除
//System.out.println(linkedList.remove(1));//根据位置删除,并返回该元素
//System.out.println(linkedList.remove());//删除并返回第一个元素
//System.out.println(linkedList.removeFirst());//删除并返回第一个元素
//栈和队列可以用的方法
// linkedList.addFirst("r");//在头部添加元素
// linkedList.addLast("v");//在尾部添加元素
// linkedList.removeFirst();//删除第一个元素
// linkedList.removeLast();//删除末尾元素
// linkedList.pop();//出栈
}
}
Vector
public class Vector_Test {
public static void main(String[] args) {
//由于三类方法功能大致一致,因此在此类中不再多赘述
Vector vector = new Vector();
//添加元素
vector.add(1);
vector.add(2);
vector.add(3);
System.out.println(vector);
}
}
set接口
HashSet
public class HashSetDemo {
public static void main(String[] args) {
/*
Set: 元素不重复
HashSet: 元素是无序的
*/
HashSet<String> set=new HashSet<>();
set.add("a");
set.add("a");//自动去重 [a, b, c, d]
set.add("b");
set.add("c");
set.add("d");
//set.clear();
//set.contains("c");
//set.isEmpty();
//set.size();
//set.iterator();//迭代器循环
//System.out.println(set);
/*
HashSet在添加元素时,是如何判断元素重复的
当我们在集合中添加一个元素时,如果每次使用equals()比较内容是否相等效率会很低
如何比较:
在底层先调用hashCode()---->Object中的hashCode()返回对象的地址(不调用这个)
会调用类中重写的hashCode(),返回的是根据内柔计算的哈希值
遍历时,会用哈希值比较是否相等,会提高效率
但是哈希值会存在问题,内容不同,哈希值相同
此种情况下,再调用equals()比较内容,这样设计即提高判断概率,又保证了安全
*/
}
}
TreeSet
public class TreesetDemo {
public static void main(String[] args) {
/*
Treeset:
不能存储重复元素
可以根据值进行排序,底层使用了属性结构,树结构本身就是有序的,
像树型结构添加元素是,如何判断元素大小及元素是否重复
向Treeset中添加的元素类型必须实现Comparable接口,重写Comparable方法
每次添加元素时调用 CompareTo方法进行元素大小判断(小于0放于左节点,等于0表示重复,大于0放于右节点)
*/
TreeSet<Integer> treeSet=new TreeSet<>();
treeSet.add(2);
treeSet.add(3);
treeSet.add(4);
treeSet.add(8);
treeSet.add(6);
treeSet.add(4);
treeSet.add(5);
treeSet.add(3);
System.out.println(treeSet);
}
}
Set接口集合迭代
set接口只有增强for循环和迭代器循环
Map接口
HashMap
public class HashMapDemo1 {
public static void main(String[] args) {
/*
Map:
数据存储是 键:值的形式存储
键不能重复,值可以重复
通过键可以找到对应的值
一个键只能映射一个值
HashMap:
键是无序的
* */
HashMap<String ,String> map=new HashMap<>();
map.put("a","aa");
map.put("b","ac");
map.put("c","bb");
map.put("e","ff");
map.put("a","aaa");//向map中添加一组键值对
//System.out.println(map.remove("b"));//删除指定键值,返回对应的值
//map.clear();//清空键值对
//System.out.println(map.isEmpty());//判断map中键值对个数是否为空;
/*
HaseMap底层数据结构:
哈希表
链表
红黑树
1.用key计算哈希值
*/
//map的遍历
//方法一:先拿到所有的键, 遍历键 根据键找值
/* Set<String > keyset=map.keySet();
for(String key:keyset){
System.out.println(key+":"+map.get(key));
}*/
//方法二:推荐的遍历方法
Set<Map.Entry<String, String>> entries=map.entrySet();
for(Map.Entry entry:entries){
System.out.println(entry.getKey()+":"+entry.getValue());
}
}
}public class HashMapDemo1 {
public static void main(String[] args) {
/*
Map:
数据存储是 键:值的形式存储
键不能重复,值可以重复
通过键可以找到对应的值
一个键只能映射一个值
HashMap:
键是无序的
* */
HashMap<String ,String> map=new HashMap<>();
map.put("a","aa");
map.put("b","ac");
map.put("c","bb");
map.put("e","ff");
map.put("a","aaa");//向map中添加一组键值对
//System.out.println(map.remove("b"));//删除指定键值,返回对应的值
//map.clear();//清空键值对
//System.out.println(map.isEmpty());//判断map中键值对个数是否为空;
/*
HaseMap底层数据结构:
哈希表
链表
红黑树
1.用key计算哈希值
*/
//map的遍历
//方法一:先拿到所有的键, 遍历键 根据键找值
/* Set<String > keyset=map.keySet();
for(String key:keyset){
System.out.println(key+":"+map.get(key));
}*/
//方法二:推荐的遍历方法
Set<Map.Entry<String, String>> entries=map.entrySet();
for(Map.Entry entry:entries){
System.out.println(entry.getKey()+":"+entry.getValue());
}
}
}
TreeMap
public class TreeMap_Test {
public static void main(String[] args) {
/*
TreeMap
底层使用树结构
键可以排序
键元素类型必须实现Comparable接口,重写方法comparableTo()
*/
TreeMap<Integer,String> treeMap = new TreeMap<>();
treeMap.put(1,"qq");
treeMap.put(2,"wx");
treeMap.put(3,"tx");
treeMap.put(4,"fb");
System.out.println(treeMap);
}
}
Hashtable
public class HashtableDemo {
public static void main(String[] args) {
/*
Hashtanle:
方法上添加了synchronized锁
Hasetable中不能存储为null的键和为null的值
HashMap可以存储为null的键和为jnull的值
*/
}
}
Map接口集合迭代
public class Map_For_Test {
public static void main(String[] args) {
HashMap<String,String> map = new HashMap<>();
map.put("a","bc");
map.put("d","ef");
map.put("j","kl");
map.put("g","hi");
map.put("a","sdf");
//Map遍历
//1、先拿所有的键,遍历键,根据键找值
Set<String> keySet = map.keySet();
for(String key : keySet){
System.out.println(key + ":" + map.get(key));
}
//2、推荐
Set<Map.Entry<String,String>> entries = map.entrySet();
for(Map.Entry entry : entries){
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
}
Collections类
public class Collections_Test {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
//添加
list.add(0);
list.add(1);
list.add(2);
Collections.addAll(list, 7,9,5);
//排序
Collections.sort(list);
//自定义排序
// Collections.sort(list, new Comparator<Integer>() {
// @Override
// public int compare(Integer o1, Integer o2) {
// return o2.intValue() - o1.intValue();//降序
// return o1.intValue() - o2.intValue();//升序
// }
// });
//二分查找
System.out.println(Collections.binarySearch(list,1));
System.out.println(Collections.binarySearch(list,10));
//指定位置元素交换
Collections.swap(list,0,1);
ArrayList<Integer> list1 = new ArrayList<>();
Collections.addAll(list1, 7,9,5,8,4,6,3);
//将原集合复制到新集合中,新集合size需大于等于原集合size
Collections.copy(list1,list);
//最大最小值
Collections.max(list);
Collections.min(list1);
//把某集合填充为指定元素
Collections.fill(list,0);
//把某集合中旧元素全部替换为指定元素
Collections.replaceAll(list,0,1);
//把某集合颠倒
Collections.reverse(list1);
//随机排序
Collections.shuffle(list1);
System.out.println(list);
System.out.println(list1);
}
}
泛型
public class Generic_Test<T, E> {
/*
默认情况下集合类中可以添加任意类型
泛型:即参数化类型
*/
T data;
E elem;
public Generic_Test(T data) {
this.data = data;
}
public E getElem() {
return elem;
}
public void setElem(E elem) {
this.elem = elem;
}
public T getData() {
return data;
}
public Generic_Test(T data, E elem) {
this.data = data;
this.elem = elem;
}
public void setData(T data) {
this.data = data;
}
public static void main(String[] args) {
Generic_Test<Integer,String> genericTest = new Generic_Test(1,"A");
genericTest.setData(1);
genericTest.getData();
//未提供类型即默认为Object
Generic_Test genericTest1 = new Generic_Test(1);
}
}
public class A<T> {
/*
泛型类
*/
T data;
}
public class B<T> extends A<T>{
/*
当一个类继承一个泛型类时,该子类也必须声明为泛型类
public class B<T> extends A<T>
当一个类继承一个泛型类时,那么就该必须明确父类泛型类型
public class B extends A<String>
接口也与上述一致
*/
public static void main(String[] args) {
B<String> b = new B();
b.data = "b";
}
}