博主前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住也分享一下给大家,
点击跳转到网站
一、ArrayList:作为list接口的主要实现类;线程不安全,效率高;底层使用Object[] elementData存储
2、list接口中的常用方法
@Test
public void test1(){
//1.List集合类中元素有序(即添加顺序和取出顺序一致)、且可重复
List list = new ArrayList();
list.add("jack");
list.add("tom");
list.add("mary");
list.add("tom");
System.out.println("list=" + list);
//2.List集合中的每个元素都有其对应的顺序索引,即支持索引
//索引是从0开始的
System.out.println(list.get(3));//tom
ArrayList list=new ArrayList();
list.add(45);
list.add("aa");
list.add("你好");
list.add("456");
System.out.println(list);
//1.void add(int index,Object ele):在index位置插入ele元素
list.add(1,"bb");
System.out.println(list);
//2.boolean addAll(int index,Collection eles):从index位置开始将eles中的所有元素添加进来
List list1 = Arrays.asList(1, 2, 3);
list.addAll(list1);
System.out.println(list);
System.out.println(list.size());
//3.Object get(int index):获取指定index位置元素的值
Object dd = list.get(1);
System.out.println(dd);
//4.int indexOf(Object obj),返回obj在当前集合中首次出现的位置
int obj = list.indexOf("aa");
System.out.println(obj);
//5.int LastIndexOf(Object obj),返回obj在当前集合中末次出现的位置
int lastIndexOf = list.lastIndexOf(45);
System.out.println(lastIndexOf);
//6.Object remove(int index),移除指定index位置的元素,并返回此元素
list.remove(2);
System.out.println(list);
//7.Object set(int index,Object ele),设置指定index位置的元素为ele
list.set(0,78);
System.out.println(list);
//8.List subList(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的(左闭右开)子集合
System.out.println(list.subList(3,5));
}
输出结果为:
[45, aa, 你好, 456]
[45, bb, aa, 你好, 456]
[45, bb, aa, 你好, 456, 1, 2, 3]
8
bb
2
0
[45, bb, 你好, 456, 1, 2, 3]
[78, bb, 你好, 456, 1, 2, 3]
[456, 1]
List接口的相关练习
public class ListExercise02 {
@SuppressWarnings({"ALL"})
public static void main(String[] args) {
// List list = new ArrayList();
// List list = new LinkedList();
List list = new Vector();
Book book = new Book("红楼梦", 10.5, "曹雪芹");
Book book1 = new Book("西游记", 7.4, "吴承恩");
Book book2 = new Book("水浒传", 9.1, "施耐庵");
list.add(book);
list.add(book1);
list.add(book2);
for (Object obj : list) {
System.out.println(obj);
}
sort(list);
System.out.println("排序后");
for (Object obj : list) {
System.out.println(obj);
}
}
//冒泡排序,价格从小到大
public static void sort(List list) {
int listSize = list.size();
for (int i = 0; i < listSize - 1; i++) {
for (int j = 0; j < listSize - 1 - i; j++) {
Book book1 = (Book) list.get(j);
Book book2 = (Book) list.get(j + 1);
if (book1.getPrice() > book2.getPrice()) {//交换
list.set(j, book2);
list.set(j + 1, book1);
}
}
}
}
}
class Book {
private String name;
private double price;
private String author;
public Book(String name, double price, String author) {
this.name = name;
this.price = price;
this.author = author;
}
@Override
public String toString() {
return "名称:" + name + "\t价格:" + price + "\t作者:" + author;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
输出结果如下:
名称:红楼梦 价格:10.5 作者:曹雪芹
名称:西游记 价格:7.4 作者:吴承恩
名称:水浒传 价格:9.1 作者:施耐庵
排序后
名称:西游记 价格:7.4 作者:吴承恩
名称:水浒传 价格:9.1 作者:施耐庵
名称:红楼梦 价格:10.5 作者:曹雪芹
以上就是常用的list集合中的方法,仅供参考学习!
@SuppressWarnings({"all"})
public class ArrayListDetail {
public static void main(String[] args) {
//可以放所有元素,包括null元素
//ArrayList 是线程不安全的,可以看源码 没有synchronized
/*
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
*/
ArrayList arrayList = new ArrayList();
arrayList.add(null);
arrayList.add("jack");
arrayList.add(null);
System.out.println(arrayList);
}
}
输出结果如下:
[null, jack, null]
ArrayList的底层源码分析,先看结论
Vector的底层源码分析
分析Vector源码代码如下:
public class Vector_ {
public static void main(String[] args) {
Vector vector = new Vector(8);
for (int i = 0; i < 10; i++) {
vector.add(i);
}
vector.add(100);
System.out.println("vector=" + vector);
//解读源码:
//1.new Vector() 底层
/*
public Vector() {
this(10);
}
补充:如果是Vector vector = new Vector(8);
走的方法:
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
2.vector.add(i);
2.1 //下面这个方法就添加数据到vector集合
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
2.2 确定是否需要扩容 条件:minCapacity - elementData.length > 0
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
2.3 //如果需要的数组大小不够用,就扩容,扩容的算法
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
//就是扩容两倍
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
*/
}
}
Vector和ArrayList的比较如下:
LinkedList的全面说明
LinkedList底层结构如下
演示双向链表,代码如下
public class LinkedList0 {
public static void main(String[] args) {
//模拟一个简单的双向链表
Node jack = new Node("jack");
Node tom = new Node("tom");
Node ly = new Node("ly");
//连接三个结点,形成双向链表
//jack->tom->ly
jack.next = tom;
tom.next = ly;
//ly->tom->jack
ly.pre = tom;
tom.pre = jack;
Node first = jack;//让first引用指向jack,就是双向链表的头结点
Node last = ly;//让last引用指向ly,就是双向链表的尾结点
//演示从头到尾进行遍历
System.out.println("===演示从头到尾进行遍历===");
while (true) {
if (first == null) {
break;
}
//输出first信息
System.out.println(first);
first = first.next;
}
//演示,从尾到头进行遍历
System.out.println("===从尾到头进行遍历===");
while (true) {
if (last == null) {
break;
}
System.out.println(last);
last = last.pre;
}
//演示链表添加对象/数据
//要求:在tom与ly之间,插入一个对象,smith
//1.先创建一个Node结点,name就是smith
Node smith = new Node("smith");
//下面就把smith加入到双向链表了
smith.next = ly;
smith.pre = tom;
tom.next = smith;
ly.pre = smith;
first = jack;
System.out.println("===演示从头到尾进行遍历===");
while (true) {
if (first == null) {
break;
}
System.out.println(first);
first = first.next;
}
System.out.println("===从尾到头进行遍历===");
last = ly;
while (true) {
if (last == null) {
break;
}
System.out.println(last);
last = last.pre;
}
}
}
//定义一个Node类,Node对象表示双向链表的一个结点
class Node {
public Object item;//真正存放数据
public Node next; //指向下一个结点
public Node pre;//指向前一个结点
public Node(Object name) {
this.item = name;
}
@Override
public String toString() {
return "Node name=" + item;
}
}
输出结果如下
===演示从头到尾进行遍历===
Node name=jack
Node name=tom
Node name=ly
===从尾到头进行遍历===
Node name=ly
Node name=tom
Node name=jack
===演示从头到尾进行遍历===
Node name=jack
Node name=tom
Node name=smith
Node name=ly
===从尾到头进行遍历===
Node name=ly
Node name=smith
Node name=tom
Node name=jack
LinkedList底层源码分析,代码如下
public class LinkedListCRUD {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
linkedList.add(1);
linkedList.add(2);
linkedList.add(3);
System.out.println("linkedList=" + linkedList);
//演示一个删除
linkedList.remove();//这里默认删除是第一个结点
System.out.println("linkedList=" + linkedList);
//修改某个结点对象
linkedList.set(1, 99);
System.out.println("linkedList=" + linkedList);
//得到某个结点对象
Object o = linkedList.get(1);
System.out.println(o);//99
//因为LinkedList是实现了List接口,遍历方式
System.out.println("===LinkedList遍历使用迭代器===");
Iterator iterator = linkedList.iterator();
while (iterator.hasNext()) {
Object linkedList1 = iterator.next();
System.out.println("linkedList=" + linkedList1);
}
//使用增强for循环
System.out.println("===使用增强for循环===");
for (Object o1 : linkedList) {
System.out.println(o1);
}
System.out.println("===LinkedList遍历使用普通for循环===");
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.get(i));
}
//源码阅读
//1. LinkedList linkedList = new LinkedList();
/*
public LinkedList() {}
2.这时linkedList的属性 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.remove();//这里默认删除是第一个结点
1.执行的是
public E remove() {
return removeFirst();
}
2.执行
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;
}
*/
}
}
输出结果如下
linkedList=[1, 2, 3]
linkedList=[2, 3]
linkedList=[2, 99]
99
===LinkedList遍历使用迭代器===
linkedList=2
linkedList=99
===使用增强for循环===
2
99
===LinkedList遍历使用普通for循环===
2
99