持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
1、关于List接口
1)List集合存储元素特点:有序可重复
有序:List集合中的元素有下标,从0开始,以1递增;
可重复:存储一个1,还可以再存储1;
2)List接口中特有的常用方法:
添加元素到指定位置 void add(int index,E element)
返回列表中指定位置的元素 Object get(int index)
返回列表中第一个出现的指定元素的索引,如果不包含返回-1 int intdexOf(Object c)
返回列表中最后出现的指定元素的索引,如果不包含返回-1 int lastIndexOf(Object c)
移除列表中指定位置的元素(可选操作) Object move(Object o)
用指定元素替换列表中指定位置的元素(可选操作) Object set(int index,E element)
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class asdf{
public static void main(String[] args) {
//调用List特有的方法需要创建List引用
List myList = new ArrayList();
//添加元素
myList.add("A");//默认都向集合末尾添加元素
myList.add("B");
myList.add("C");
myList.add("D");
myList.add("E");
//在列表的指定位置插入元素(第一个参数是下标)
myList.add(1,"KING");//这个方法使用的不多,因为效率太低
//迭代
Iterator it = myList.iterator();
while(it.hasNext()){
Object ect = it.next();
System.out.println(ect);
}
//根据下标获取元素
Object firstObj = myList.get(0);
System.out.println(firstObj);
//因为有下标,所以List集合有自己比较独特的遍历方式【通过下标】
for(int i = 0;i<mylist.size();i++){
Object obj = myList.get(i);
System.out.println(obj);
}
}
}
2、ArrayList集合
2.1 Arrays工具类的使用
判断两个数组是否相等。 boolean equals(int[] a,int[] b)
输出数组信息。 String toString(int[] a)
将指定值填充到数组之中。 void fill(int[] a,int val)
对数组进行排序。 void sort(int[l a)
对排序后的数组进行二分法检索指定的值。 int binarySearch(int[] a,int key)
2.2 初始化容量
1)默认初始化容量是10(JDK13新特性:底层先创建了一个长度为0的数组,当添加第一个元素的时候,初始化容量为10)
注意:size方法测的是集合中元素的个数,不是集合的容量
2)集合底层是一个Object [ ] 数组
3)构造方法:
new ArrayList();
new ArrayList(20);
//指定初始化容量100
List myList2 = new ArrayList(100);
//创建一个HashSet集合
Collection c = new HashSet();
//添加元素到Set集合
c.add(100);
c.add(200);
c.add(900);
//通过这个构造方法就可以将HashSet集合转换成List集合
List myList3 = new ArrayList(c);
for(int i =0;i<myList3.size();i++){
System.out.println(myList3.get(i));
}
2.3 扩容
1)默认初始化容量是10,容量满了之后如果再添加元素,自动扩容,扩容的大小是原来的1.5倍
2)ArrayList的底层是数组,尽可能少的扩容,因为数组扩容效率比较低。建议在使用ArrayList的是初始化容量给顶一个预估计的初始化容量,减少扩容
2.4 关于数组
优点:检索效率比较高;
缺点:随机增删元素的效率比较低;
向数组元素末尾添加元素,效率很高,不受影响;
3、位运算
// 5
// >> 1 二进制右移1位
// >> 2 二进制右移2位
// 10的二进制:00001010 【10】
// 10的二进制右移1位是:00000101 【5】
左移是乘以,右移是除以 2的n次方倍,n为移动的位数
4、LinkedList集合
4.1 链表的优缺点
链表的优点:空间存储内存地址不连续,随机增删元素效率较高(因为增删元素不涉及到大量的元素位移)
链表的缺点:查询效率较低,每一次查找某个元素的时候都需要从头节点开始往下遍历
ArrayList之所以检索效率高,不是单纯因为下标的原因,是因为底层数组发挥的作用
LinkedList集合照样有下标,但是检索某个元素的时候效率比较低,因为只能从头节点开始一个一个遍历
4.2 Java实现单链表
public class asdf{
public static void main(String[] args) {
Link link = new Link();
link.add(100);
link.add(200);
link.add(300);
System.out.println(link.size);
}
}
class Node{
//存储的数据
Object data;
//下一个结点的内存地址
Node next;
public Node(){
}
public Node(Object data,Node next){
this.data = data;
this.next = next;
}
}
class Link {
//头指针
Node header = null;
int size = 0;
public int size(){
return size;
}
//向链表中添加元素的方法
public void add(Object data) {
//创建一个新的节点对象
//让之前单链表的末尾节点next指向新节点对象
if(header == null) {
//说明还没有节点,new一个新的节点对象,作为头节点对象
header = new Node(data,null);
}else{
//说明头结点已经有了
//找出当前末尾节点,让当前末尾节点的next是新节点
Node currentLastNode = findLast(header);
currentLastNode.next = new Node(data,null);
}
size++;
}
//专门查找末尾结点的方法
private Node findLast(Node node) {
if(node.next == null) {
//如果节点的next是空则为末尾节点
return node;
}
return findLast(node.next);//递归
}
//删除链表中的某个数据的方法
public void remove(Object obj){
}
//修改链表中的某个数据元素的方法
public void modify(Object newobj){
}
//查找链表中某个元素的方法
public int find(Object obj){
return 1;
}
}
4.3 关于LinkedList
1)LinkedList集合没有初始化容量
2)最初这个链表中没有任何元素。first和last引用都是null
3)不管是LinkedList还是ArrayList,以后写代码不需要关系是哪个集合,我们需要面向接口编程,调用的方法都是接口中的方法
List list2 = new ArrayList();//这样写表示底层用的是数组
List list2 = new LinkedList();//这样写表示底层用的是双向链表
List2.add("123");
List2.add("456");
List2.add("789");
//这些方法都是面向的是接口编程
5、Vector集合
5.1 关于Vector集合
1)底层是一个数组
2)初始化容量是10
3)超过10后自动扩容,每次扩容是原容量的2倍
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
public class java{
public static void main(String[] args) {
List l = new Vector();
l.add("123");
l.add("456");
l.add("789");
l.add("122");
Iterator as = l.iterator();
while(as.hasNext()){
Object object = as.next();
System.out.println(object);
}
}
}
4)Vector中的所有方法都是线程同步的,都带有synchronized关键字,是线程安全的。效率较低,使用较少
5.2 将不安全的ArrayList集合转换成线程安全
使用集合工具类 java.utill.Collections;
注意:java.utill.Collection 是集合接口
java.utill.Collections 是集合工具类
List myList = new ArrayList();//非线程安全的
//变成线程安全的
Collection.synchronizedList(myList);
//现在mylist就是线程安全的了
6、泛型
6.1 关于泛型
jdk1.5后的新特性
泛型这种语法机制只能在程序编译阶段起作用,只是给编译器参考的【运行阶段泛型意义不大】
优点:
1)集合中存储的元素类型统一了
2)从集合中取出的元素类型是泛型指定的类型,不需要进行大量的"向下转型"
缺点:
1)导致集合中元素缺乏多样性
2)调用父类中特有的方法不需要向下转型,但调用子类中特有的方法还是需要向下转型
6.2 泛型的具体使用
public class java{
public static void main(String[] args) {
/*List l = new Vector();
Cat cat = new Cat();
Dog dog = new Dog();
l.add(cat);
l.add(dog);
Iterator it = l.iterator();
while(it.hasNext()){
Object object = it.next();
// 使用泛型前需要向下转型
if(object instanceof Animal){
Animal a =(Animal)object;
a.move();
}
}*/
//使用泛型后
List <Animal> l = new Vector<Animal>();
//指定list集合只能存储Animal,那么存储String就编译报错了
//这样使用泛型之后,集合中元素的数据类型更加统一
Cat cat = new Cat();
Dog dog = new Dog();
l.add(cat);
l.add(dog);
//获取迭代器
//表示迭代器迭代的是Animal类型
Iterator <Animal>it = l.iterator();
while(it.hasNext()){
//使用迭代之后返回的数据都是Animal类型的,不需要强制类型转换
Animal a= it.next();
a.move();
}
}
}
class Animal{
public void move(){
System.out.println("动物在移动");
}
}
class Cat extends Animal{
public void move(){
System.out.println("猫在吃鱼");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗在吃肉");
}
}
6.3 类型自动推断【钻石表达式】
ArrayList<这里的类型会自动推断>(),前提是jdk8之后才允许
List myList = new ArrayList <> ();
6.4 自定义泛型
<>尖括号里面的是一个标识符,随便写
一般是,
E是Element单词首字母
T是Type单词首字母
public class asdf<E>{
public void Do(E o){
System.out.println(o);
}
public static void main(String[] args) {
asdf<String> gt = new asdf<>();
gt.Do("ssd");
}
}
7、foreach【增强for循环】
jdk5.0之后的新特性
7.1 语法格式
for(元素类型 变量名:数组或集合){
System.out.println(变量名);
}
7.2 增强for(foreach)
int[] arr = {43,34,3241,5463,23,1};
for(int data:arr){
System.out.println(data);
}
data代表数组中的每一个元素,可以改变
缺点:没有下标
7.3 集合使用foreach
//创建List集合
List<String>strList = new ArrayList<>();
//添加元素
strList.add("hello");
strList.add("world");
strList.add("kitty");
//遍历使用选代器方式
Iterator<String> it = strlist.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
//使用下标方式(只针对于有下标的集合)
for(int i = B; i < strList.size(); i++){
System.out.println(strList.get(i));
}
//使用oreach
for(String s:strlist){ // 因为泛型使用的是String关星,所以是:String s
System.out.println(s);
}