javase(2023/11/24)

1、Array类

package zhh.chapter13.array;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * @author longbownice
 * @version 1.0
 *
 * 自定义sort原理
 */
public class Array_ {
    public static void main(String[] args) {

        //1、toString
        //以字符串形式打印数组,用[]包起来
        Integer[] integers = {1, 20, 90};
        //遍历数组
        //1 20 90
         for(int i = 0; i < integers.length; i++) {
         System.out.print(integers[i]+" ");
         }
        //直接使用 Arrays.toString 方法,显示数组
        //[1, 20, 90]
        System.out.println(Arrays.toString(integers));


        //2、演示 sort 方法的使用
        //因为数组是引用类型,所以通过 sort 排序后,会直接影响到 实参 arr
        //sort 重载的,也可以通过传入一个接口 Comparator 实现定制排序
        //调用 定制排序 时,传入两个参数
        // (1) 排序的数组 arr
        // (2) 实现了 Comparator 接口的匿名内部类 , 要求实现 compare 方法
        //     这里体现了接口编程的方式 , 看看源码,就明白

        // 源码分析
        //(1) Arrays.sort(arr, new Comparator())
        //(2) 最终到 TimSort 类的 private static <T> void binarySort
        // (T[] a, int lo, int hi, int start,Comparator<? super T> c)
        //(3) 执行到 binarySort 方法的代码, 会根据动态绑定机制 c.compare()执行我们传入的
        // 匿名内部类的 compare (),这里用到了一点二叉排序(折半插入排序)
        // while (left < right) {
            // int mid = (left + right) >>> 1;
            (待插入的数,有序序列的中间值)
            // if (c.compare(pivot, a[mid]) < 0)
            //当return(pivot-a[mid])时,即待插入的数小于中间点时
            //right左移,最后找着的插入位置一定在左边,即较小的数最后插入到左边
            //类似于冒泡排序(从右边开始)中if([j]<[j-1]) {[j]左移}
            //即实现了从小到大排序
            //总之,前-后升序,后-前降序(且不改变原来顺序,不是left <= right)
            //反之,从大到小
            // right = mid;
            // else
            // left = mid + 1;
        // }
        //(4) new Comparator() {
        // @Override
        // public int compare(Object o1, Object o2) {
            // Integer i1 = (Integer) o1;
            // Integer i2 = (Integer) o2;
            // return i2 - i1;
            // }
        // }
        //(5) public int compare(Object o1, Object o2) 返回的值>0 还是 <0
        // 会影响整个排序结果, 这就充分体现了 接口编程+动态绑定+匿名内部类的综合使用
        // 将来的底层框架和源码的使用方式,会非常常见

        // 默认排序方法
        //Arrays.sort(arr);
        //定制排序
        Integer arr[] = {1, -1, 7, 0, 89};
        Arrays.sort(arr, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Integer i1 = (Integer) o1;
                Integer i2 = (Integer) o2;
                return i2 - i1;
            }
        });
        System.out.println("===排序后===");
        System.out.println(Arrays.toString(arr));

        //3、binarySearch二分查找(数组有序,返回下标)
        //如果数组中不存在该元素,就返回 return -(low + 1),low是这个数如果存在所在的位置
        Integer[] arr1 = {1, 2, 90, 123, 567};
        int index = Arrays.binarySearch(arr1, 567);
        System.out.println("index=" + index);//4
        System.out.println(Arrays.binarySearch(arr1,999));//-(5+1)=-6

        //4、copyOf 数组元素的复制
        // 老韩解读
        //1. 从 arr 数组中,拷贝 前n 个元素到 newArr 数组中
        //2. 如果拷贝的长度 > arr.length 就在新数组的后面 增加 null
        //3. 如果拷贝长度 < 0 就抛出异常 NegativeArraySizeException
        //4. 该方法的底层使用的是 System.arraycopy()
        Integer[] newArr = Arrays.copyOf(arr1, 3);//[1, 2, 90]
        System.out.println(Arrays.toString(newArr));//[1, 2, 90]
        newArr = Arrays.copyOf(arr1, 7);
        System.out.println(Arrays.toString(newArr));//[1, 2, 90, 123, 567, null, null]

        //ill 数组元素的填充
        //1. 使用 val 去填充 num 数组,可以理解成是替换原理的元素
        Integer[] num = new Integer[]{9,3,2};
        System.out.println(Arrays.toString(num));//[9, 3, 2]
        Arrays.fill(num, 99);
        System.out.println("==num 数组填充后==");
        System.out.println(Arrays.toString(num));//[99, 99, 99]

        //equals
        // 比较两个数组元素内容是否完全一致
        //1. 如果 arr 和 arr2 数组的元素一样,则返回 true;
        //2. 如果不是完全一样,就返回false
        Integer[] arr2 = {1, 2, 90, 123};
        boolean equals = Arrays.equals(arr, arr2);
        System.out.println("equals=" + equals);//false

        //asList 将一组值
        // 转换成list
        //老韩解读
        //1. asList 方法,会将 (2,3,4,5,6,1)数据转成一个 List 集合
        //2. 返回的 asList 编译类型 List(接口)
        //3. asList 运行类型 java.util.Arrays#ArrayList, 是 Arrays 类的
        // 静态内部类 private static class ArrayList<E> extends AbstractList<E>
        // implements RandomAccess, java.io.Serializable
        List asList = Arrays.asList(2,3,4,5,6,1);
        System.out.println("asList=" + asList);
        System.out.println("asList 的运行类型" + asList.getClass());

    }
}
自定义sort应用
package zhh.chapter13.array;

import java.util.Arrays;
import java.util.Comparator;

/**
 * @author longbownice
 * @version 1.0
 *
 * 自定义sort应用
 *
 */
public class ArraySort {
    public static void main(String[] args) {
        Book[] book=new Book[4];
        book[0]=new Book("红楼梦",100);
        book[1]=new Book("金瓶梅新",90);
        book[2]=new Book("青年文摘20年",5);
        book[3]=new Book("java从入门到放弃",300);



        //price从小到大
        Arrays.sort(book, new Comparator<Book>() {
            @Override
            public int compare(Book o1, Book o2) {
                //如果价格是double
                //也可以用double接受,根据相减结果用ifelse返回1或-1;
                int d1=o1.getPrice();
                int d2=o2.getPrice();
                return d1-d2;
            }
        });
        for(Book b:book){
            System.out.println(b);
        }
        System.out.println();

        Arrays.sort(book, new Comparator<Book>() {
            @Override
            public int compare(Book o1, Book o2) {
                int d1=o1.getPrice();
                int d2=o2.getPrice();
                return d2-d1;
            }
        });
        for(Book b:book){
            System.out.println(b);
        }
        System.out.println();

        Arrays.sort(book, new Comparator<Book>() {
            @Override
            public int compare(Book o1, Book o2) {
                int d1=o1.getName().length();
                int d2=o2.getName().length();
                return d2-d1;
            }
        });
        for(Book b:book){
            System.out.println(b);
        }

//        print
//        Book{name='青年文摘20年', price=5}
//        Book{name='金瓶梅新', price=90}
//        Book{name='红楼梦', price=100}
//        Book{name='java从入门到放弃', price=300}
//
//        Book{name='java从入门到放弃', price=300}
//        Book{name='红楼梦', price=100}
//        Book{name='金瓶梅新', price=90}
//        Book{name='青年文摘20年', price=5}
//
//        Book{name='java从入门到放弃', price=300}
//        Book{name='青年文摘20年', price=5}
//        Book{name='金瓶梅新', price=90}
//        Book{name='红楼梦', price=100}



    }

}
class Book{
    private String name;
    private int price;

    public Book(String name, int price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

2、System类

package zhh.chapter13.system;

import java.util.Arrays;

/**
 * @author longbownice
 * @version 1.0
 *
 *  System 类常见方法和案例
 */

public class System_ {
    public static void main(String[] args) {

        //1、exit 退出当前程序
        // exit(0) 表示程序退出
        // 0 表示一个状态 , 正常的状态
        System.out.println("ok1");
//        System.exit(0);//执行的话就结束进程了,下面不再执行
        System.out.println("ok2");

        //2、arraycopy :复制数组元素,比较适合底层调用,
        // 一般使用 Arrays.copyOf 完成复制数组

        // System.arraycopy(src, 0, dest, 0, src.length);
        // src 源数组
        // * @param src  the source array.
        // srcPos: 从源数组的哪个索引位置开始拷贝
        // * @param srcPos  starting position in the source array.
        // dest : 目标数组,即把源数组的数据拷贝到哪个数组
        // * @param dest  the destination array.
        // destPos: 把源数组的数据拷贝到 目标数组的哪个索引
        // * @param destPos starting position in the destination data.
        // length: 从源数组拷贝多少个数据到目标数组
        // * @param length the number of array elements to be copied.
        int[] src={1,2,3};
        int[] dest = new int[3];// dest 当前是 {0,0,0}
        System.arraycopy(src, 0, dest, 0, src.length);
        System.out.println("dest=" + Arrays.toString(dest));//[1, 2, 3]
        System.arraycopy(src, 1, dest, 0, 2);
        System.out.println("dest=" + Arrays.toString(dest));//[2, 3, 3]

        //3、currentTimeMillens:返回当前时间距离 1970-1-1 的毫秒数
        System.out.println(System.currentTimeMillis());//1700745243726

        //4、垃圾回收,以后再详细了解
        System.gc();
    }
}

3、BigInteger 和 BigDecimal 类

应用场景:
1)Biglnteger适合保存比较大的整型
2) BigDecimal适合保存精度更高的浮点型(小数)

  • add 加
  • subtract减
  • multiply乘
  • divide除
     
package zhh.chapter13.bigdate;

import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * @author longbownice
 * @version 1.0
 */
public class BigDate {
    public static void main(String[] args) {
        BigInteger bigInteger = new BigInteger("99999999999955555555558888888");
        BigInteger bigInteger1 = new BigInteger("2");
        BigInteger add = bigInteger.add(bigInteger1);
        System.out.println("add: "+add);
        BigInteger subtract = bigInteger.subtract(bigInteger1);
        System.out.println("subtract: "+subtract);
        BigInteger multiply = bigInteger.multiply(bigInteger1);
        System.out.println("multiply: "+multiply);
        BigInteger divide = bigInteger.divide(bigInteger1);
        System.out.println("divide: "+divide);
//        print
//        add: 99999999999955555555558888890
//        subtract: 99999999999955555555558888886
//        multiply: 199999999999911111111117777776
//        divide: 49999999999977777777779444444

        BigDecimal bigDecimal = new BigDecimal("9.9999999999999999999999999999");
        BigDecimal bigDecimal1 = new BigDecimal("1.22");
        BigDecimal add1 = bigDecimal.add(bigDecimal1);
        System.out.println("add1: "+add1);
        BigDecimal subtract1 = bigDecimal.subtract(bigDecimal1);
        System.out.println("subtract1: "+subtract1);
        BigDecimal multiply1 = bigDecimal.multiply(bigDecimal1);
        System.out.println("multiply1: "+multiply1);
        //这里不指定BigDecimal.ROUND_CEILING(保留分子精度),会抛出异常ArithmeticException
//        BigDecimal divide1 = bigDecimal.divide(bigDecimal1);
//        System.out.println("divide1: "+divide1);
        BigDecimal divide2 = bigDecimal.divide(bigDecimal1,BigDecimal.ROUND_CEILING);
        System.out.println("divide2: "+divide2);
//        print
//        add1: 11.2199999999999999999999999999
//        subtract1: 8.7799999999999999999999999999
//        multiply1: 12.199999999999999999999999999878
//        divide2: 8.1967213114754098360655737705

    }
}

4、日期类

package zhh.chapter13.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

/**
 * @author longbownice
 * @version 1.0
 *
 * 第一代日期
 * Date类使用
 */
public class Date_ {
    public static void main(String[] args) throws ParseException {
        Date date = new Date();
        System.out.println(date);//Fri Nov 24 10:01:15 CST 2023
        //从1970-01-01 00:00:00经过3600000毫秒(1小时)的时间,在加上8(相差八个时区)
        Date date1 = new Date(3600000);
        System.out.println(date1);//Thu Jan 01 09:00:00 CST 1970

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        System.out.println(sdf.format(date));//2023-11-24 10-04-32

        //符合格式日期的字符串可以转换成date型日期
        String s="2030-10-22 18-20-10";
        //有可能抛出异常ParseException
        Date parse = sdf.parse(s);
        System.out.println(sdf.format(parse));//2023-11-24T02:42:38.338Z 默认时区

        //时间戳和日期转换
        Instant now = Instant.now();
        System.out.println(now);

        Date from = Date.from(now);
        System.out.println(now.getNano());//324000000
        System.out.println(sdf.format(date));//2023-11-24 10-42-38
        Instant instant = from.toInstant();
        System.out.println(instant);//2023-11-24T02:42:38.338Z

        //可以通过Instance实现LocalDateTime和Date的转换
        // 使用ZoneId定义时区(可以根据需要选择不同的时区)
        ZoneId zoneId = ZoneId.of("Asia/Shanghai");
        LocalDateTime localDateTime = now.atZone(zoneId).toLocalDateTime();
        System.out.println(localDateTime);//2023-11-24T11:09:24.854



    }
}

package zhh.chapter13.date;

import java.util.Calendar;

/**
 * @author longbownice
 * @version 1.0
 *
 * 第二代日期
 * Calendar类使用
 */
public class Calendar_ {
    public static void main(String[] args) {
        //构造器protected
        //可以通过 getInstance() 来获取实例
        Calendar instance = Calendar.getInstance();

        System.out.println(instance);//打印很多相关字段

        //如果我们需要按照 24 小时进制来获取时间, Calendar.HOUR ==改成=> Calendar.HOUR_OF_DAY
        // 这里为什么要 + 1, 因为 Calendar 返回月时候,是按照 0 开始编号
        //Calender 没有专门的格式化方法,所以需要程序员自己来组合显示
        System.out.println(instance.get(Calendar.YEAR) + "-" + (instance.get(Calendar.MONTH) + 1) + "-"
                + instance.get(Calendar.DATE) + " " + instance.get(Calendar.HOUR_OF_DAY) + "-"
                + instance.get(Calendar.MINUTE) + "-" + instance.get(Calendar.SECOND));
        //2023-11-24 10-25-24

    }
}

package zhh.chapter13.date;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * @author longbownice
 * @version 1.0
 *
 * 第三代日期
 *
 * 前面两代日期类的不足分析
 * JDK 1.0中包含了一个java.util.Date类,
 * 但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用了。而Calendar也存在问题是:
 *
 * 1)可变性:像曰期和时间这样的类应该是不可变的。
 * 2)偏移性:Date中的年份是从1900开始的,而月份都从0开始。
 * 3)格式化:格式化只对Date有用,Calendar则不行。
 * 4)此外,它们也不是线程安全的;不能处理闰秒等(每隔2天,多出1s)。
 */
public class LocalDateTime_ {
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.now();
        System.out.println(ldt);//2023-11-24T10:35:19.793

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        System.out.println(dtf.format(ldt));//2023-11-24 10:35:19

        System.out.println(ldt.getMonth());//英文月份 NOVEMBER
        System.out.println(ldt.getYear()+"-"+ldt.getMonthValue()+"-"+ldt.getDayOfMonth()+" "
                +ldt.getHour()+":"+ldt.getMinute()+":"+ldt.getSecond());
        //2023-11-24 10:35:19

        //提供 plus 和 minus 方法可以对当前时间进行加或者减
        LocalDateTime localDateTime = ldt.plusDays(900);
        LocalDateTime localDateTime1 = ldt.plusHours(900);
        LocalDateTime localDateTime2 = ldt.minusDays(900);
        LocalDateTime localDateTime3 = ldt.minusMonths(900);
        System.out.println(dtf.format(localDateTime));//2026-05-12 10:38:51
        System.out.println(dtf.format(localDateTime1));//2023-12-31 22:38:51
        System.out.println(dtf.format(localDateTime2));//2021-06-07 10:38:51
        System.out.println(dtf.format(localDateTime3));//1948-11-24 10:38:51

        LocalDate localDate =LocalDate.now();//获取年月日
        System.out.println(localDate);//2023-11-24
        
        LocalTime now = LocalTime.now();//获取时分秒
        System.out.println(now);//11:52:09.879

    }
}

4、集合

.集合主要是两组(单列集合 , 双列集合) 

Collection 接口有两个重要的子接口 List、Set , 他们的实现子类都是单列集合

Map 接口的实现子类 是双列集合,存放的 K-V

4.1Collection 接口和常用方法

  • collection实现子类可以存放多个元素,每个元素可以是Object
  • 有些Collection的实现类,可以存放重复的元素,有些不可以
  • 有些Collection的实现类,有些是有序的(List),有些不是有序(Set)
  • Collection接口没有直接的实现子类,是通过它的子接口Set 和 List来实现的
     
package zhh.chapter14.collection_;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * @author longbownice
 * @version 1.0
 *
 * Collection接口常用方法
 * 以ArrayList为例
 */
public class Collection_ {
    @SuppressWarnings("all")
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        ArrayList arrayList1 = new ArrayList();
        arrayList1.add("zhansan");
        arrayList1.add("zhansan");
        arrayList1.add("lisi");
        arrayList1.add("wangsan");
        arrayList1.add("hzaosan");

        //增
        arrayList.add(10);//相当于new Integer(10)
        arrayList.add("jack");
        arrayList.add(true);
        arrayList.add(5.99);
        arrayList.add(arrayList1);
        //增多个
        arrayList.addAll(arrayList1);
        System.out.println(arrayList);
        //[10, jack, true, 5.99, [zhansan, zhansan, lisi, wangsan, hzaosan], zhansan, zhansan, lisi, wangsan, hzaosan]

        //删
        arrayList.remove((Integer)10);//或者(0)
        arrayList.remove("jack");
        arrayList.remove(1);
        arrayList.removeAll(arrayList1);
        System.out.println(arrayList);
        //[true, [zhansan, zhansan, lisi, wangsan, hzaosan]]

        //改
        arrayList.set(0,5.10);
        System.out.println(arrayList);
        //[5.1, [zhansan, zhansan, lisi, wangsan, hzaosan]]

        //查
        System.out.println(arrayList.contains(true));//T
        System.out.println(arrayList.containsAll(arrayList1));//F
        System.out.println(arrayList.size());//2
        arrayList.clear();
        System.out.println(arrayList.isEmpty());//T

        ArrayList arrayList2 = new ArrayList();
        arrayList2.add(new Dog("阿拉斯加",6));
        arrayList2.add(new Dog("拉布拉多",3));
        arrayList2.add(new Dog("哈士奇",7));
        arrayList2.add(new Dog("中华田园犬",5));

        //迭代器遍历(实现自Iterable)
        //快捷键itit
        //Ctrl+j显示快捷键的快捷键
        Iterator iterator = arrayList2.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();//执行过next()后,指向下一个
            System.out.println(next);
        }
        //Dog{name='阿拉斯加', age=6}
        //Dog{name='拉布拉多', age=3}
        //Dog{name='哈士奇', age=7}
        //Dog{name='中华田园犬', age=5}
        //遍历一次后,iterator指向最后一个元素
        //如果希望再次遍历,重置
        Iterator iterator1 = arrayList2.iterator();
        while (iterator1.hasNext()) {
            Object next =  iterator1.next();
            System.out.println(next);
        }

        //增强for循环遍历
        //底层还是iterator,相当于简化版iterator
        //只能遍历数组和集合
        for (Object o :arrayList2) {
            System.out.println(o);
        }
        //Dog{name='阿拉斯加', age=6}
        //Dog{name='拉布拉多', age=3}
        //Dog{name='哈士奇', age=7}
        //Dog{name='中华田园犬', age=5}

    }
}

class Dog {
    private String name;
    private int age;
    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

4.2、ArrayList底层源码

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

注意事项

  • permits all elements, including null ,ArrayList 可以加入nul,并且多个
  • ArrayList是由数组来实现数据存储的
  • ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高,无synchronized)。在多线程情况下,不建议使用ArrayList

源码分析

  • ArrayList中维护了一个Object类型的数组elementData.
  • transient Objectl] elementData; //transient表示瞬间,短暂的,表示该属性不会被序列号
  • 当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍。
  • 如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍。
     

4.3 Vector

public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable

和ArrayList几乎一样,只不过Vector是线程安全(synchronize)的。

底层也是对象数组,protected Object element[]

4.4 LinkedList 底层结构

  • LinkedList底层实现了双向链表和双端队列特点
  • 可以添加任意元素(元素可以重复),包括null
  • 线程不安全,没有实现同步
  • LinkedList底层维护了一个双向链表.
  • LinkedList中维护了两个属性first和last分别指向首节点和尾节点
  • 每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表.
  • 所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高。
     

CRUD

package zhh.chapter14.list;

import java.util.LinkedList;

/**
 * @author longbownice
 * @version 1.0
 */
public class LinkListCRUD {
    @SuppressWarnings("all")
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();

        //create
        /* 1. LinkedList linkedList = new LinkedList();
                public LinkedList() {}
        2. 这时 linkeList 的属性 first = null last = null
        3. 执行 添加
        public boolean add(E e) {
            linkLast(e);
            return true;
        }
        4.将新的结点,加入到双向链表的最后
        void linkLast(E e) {
            final Node<E> l = last;
            final Node<E> newNode = new Node<>(l, e, null);
            last = newNode;
            if (l == null)
                first = newNode;
            else
                l.next = newNode;
            size++;
            modCount++;
        }
        */
        linkedList.add(11);
        linkedList.add(22);
        linkedList.add(11);
        linkedList.add(44);
        linkedList.add(55);
        linkedList.add(66);
        System.out.println(linkedList);

        //delete

        /*
        源码 linkedList.remove(); // 这里默认删除的是第一个结点
        1. 执行 removeFirst
            public E remove() {
                return removeFirst();
            }
        2. 执行removeFirst()
            public E removeFirst() {
                final Node<E> f = first;
                if (f == null)
                    throw new NoSuchElementException();
                return unlinkFirst(f);
            }
        3. 执行 unlinkFirst, 将 f 指向的双向链表的第一个结点拿掉
            private E unlinkFirst(Node<E> f) {
                // assert f == first && f != null;
                final E element = f.item;
                final Node<E> next = f.next;
                f.item = null;
                f.next = null; // help GC
                first = next;
                if (next == null)
                    last = null;
                else
                    next.prev = null;
                size--;
                modCount++;
                return element;
            }
        */

        /* remove(Object o)
        public boolean remove(Object o) {
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null) {
                    unlink(x);
                    return true;
                }
            }
        } else {
            //从这里可以看出按对象删除遇到重名时,先删除前面的
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item)) {
                    unlink(x);
                    return true;
                }
            }
        }
        return false;
        }
         */
        linkedList.remove((Object)11);
        linkedList.remove((Object)11);
        linkedList.remove(2);
        linkedList.remove();//删除第一个
        System.out.println(linkedList);

        //update
        linkedList.set(1,999);
        System.out.println(linkedList);

        //retrieve
        System.out.println(linkedList.get(0));
        System.out.println(linkedList);
        System.out.println(linkedList.contains(999));

//        print
//        [11, 22, 11, 44, 55, 66]
//        [44, 66]
//        [44, 999]
//        44
//        [44, 999]
//        true


    }
}

ArrayList 和 LinkedList 的比较

如何选择ArrayList和LinkedList:

  1. 如果我们改查的操作多,选择ArrayList
  2. 如果我们增删的操作多,选择LinkedList
  3. 一般来说,在程序中,80%-90%都是查询,因此大部分情况下会选择ArrayList
  4. 在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另外一个模块是LinkedList,也就是说,要根据业务来进行选择
     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值