ArrayList的扩容机制
ArrayList的底层实现的数据结构为数组。数组在创建的时候是要将大小给出来再进行创建的。但是集合在新建的时候是不用在创建的时候给出具体的大小,那么ArrayList是怎么进行扩容的呢?
扩容发生的位置:add()
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
add()方法中有一个ensureCapacityInternal()方法(可以确保初始化的扩容)
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
去除List集合中的重复的内容
思路:新创建一个集合,然后将原来的集合进行遍历,利用contains()方法就可以实现功能
public class TestList {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("java");
list.add("linux");
list.add("php");
list.add("php");
list.add("python");
list.add("python");
list.add("python");
List newList = getNewList(list);
System.out.println(newList);
}
public static List getNewList(ArrayList list){
Iterator iterator = list.iterator();
ArrayList newList = new ArrayList();
while (iterator.hasNext()){
Object o = iterator.next();
if(!newList.contains(o)){
newList.add(o);
}
}
return newList;
}
}
LinkedList
代码:
/**
* LinkedList:底层的数据结构为链表,增删快查找慢
* @author kiosk
*/
public class TestLinkedList {
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.addFirst("a");
list.addFirst("b");
list.addFirst("c");
list.addFirst("d");
list.addFirst("e");
System.out.println(list);
System.out.println(list.getFirst());
System.out.println(list.getLast());
list.remove(2);
list.get(2);
System.out.println(list.removeFirst());
System.out.println(list.removeLast());
System.out.println(list);
}
}
利用LinkedList来模拟栈的结构
import java.util.LinkedList;
/**
* 用LinkedList来模拟栈的数据结构
* 进栈:addFirst()
* 出栈:removeLast()
* @author kiosk
*/
public class Stack {
private LinkedList list = new LinkedList();
/**
* 进栈的方法
* @param object
*/
public void enterStack(Object object){
list.addFirst(object);
}
/**
* 出栈的方法
* @return
*/
public Object outStack(){
return list.removeLast();
}
public boolean isEmpty(){
return list.isEmpty();
}
}
/**
* @author kiosk
*/
public class TestStack {
public static void main(String[] args) {
Stack stack = new Stack();
stack.enterStack("a");
stack.enterStack("b");
stack.enterStack("c");
stack.enterStack("d");
while (stack.isEmpty()){
stack.outStack();
}
}
}
泛型机制
泛型的使用
/**
* 泛型的使用
* @author kiosk
*/
public class Person<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
/**
* 可以在方法上定义自己的泛型
* @param w
* @param <W>
*/
public<W> void show(W w){
System.out.println(w);
}
/**
* (1)静态的方法必须声明自己的泛型,因为类上的泛型是在创建对象
* 的时候进行泛型的复制的,但是静态方法上的泛型是在类上调用的,时间段是不同的
* (2)静态的方法定义自己的泛型与类上的泛型是不同的
* @param o
* @param <O>
*/
public static<O> void method(O o){
System.out.println(o);
}
}
泛型接口
实现泛型的两种方法:
(1)
/**
* 接口的第一种实现的方法
* @author kiosk
*/
public class Demo implements Inter<String> {
@Override
public void show(String s) {
System.out.println(s);
}
}
(2)
/**
* 第二种实现泛型的方式,但是这种方法是不推荐的
* 实现接口不要自己再一次重新定义泛型
* @author kiosk
*/
public class Demo2<T> implements Inter<T> {
@Override
public void show(T t) {
}
}
泛型的通配符
任意的类型:<?>
/**
* @author kiosk
*/
public class Test3 {
public static void main(String[] args) {
List<?> list;
//利用?通配符可以代表未知的泛型,但是不能直接使用add方法。因为不知道类型
// 但是可以使用add(null)
list = new ArrayList<String>();
list = new ArrayList<Integer>();
list.add(null);
}
}
向下定义:<? extends T> T以及T的子类
例如ArrayList的addAll(Collection<? extends E> c) 方法
/**
* @author kiosk
*/
public class Test4 {
public static void main(String[] args) {
ArrayList<Person> list1 = new ArrayList<Person>();
list1.add(new Person("name",123));
list1.add(new Person("user",123));
list1.add(new Person("hello",123));
ArrayList<Student> list2 = new ArrayList<>();
list2.add(new Student("张三",10));
list2.add(new Student("李四",10));
//Student类是Person类的子类,所以可以用addAll()方法
list1.addAll(list2);
}
}
向上定义:< ?super T> T以及T的父类
三种迭代方法能能否删除的问题
普通的for循环的删除
/**
* @author kiosk
*/
public class Test4 {
public static void main(String[] args) {
ArrayList<Person> list1 = new ArrayList<Person>();
list1.add(new Person("name",123));
list1.add(new Person("name",123));
list1.add(new Person("user",123));
list1.add(new Person("hello",123));
list1.add(new Person("linux",123));
//当list1中的hello元素多个而且是连着的,就会出现删不干净的问题需要--操作
//让指向的位置回来
for (int i = 0; i < list1.size(); i++){
Person person = list1.get(i);
if(person.getName() == "name"){
//先删除后--
list1.remove(i--);
System.out.println(i);
}
System.out.println(person.getName() + "==" + person.getAge());
}
System.out.println(list1);
}
}
迭代器的删除的方法:
import com.westos.demo1.Person;
import java.util.ArrayList;
import java.util.Iterator;
/**
* 使用迭代器进行删除
* @author kiosk
*/
public class Test5 {
public static void main(String[] args) {
ArrayList<Person> list1 = new ArrayList<Person>();
list1.add(new Person("name",123));
list1.add(new Person("name",123));
list1.add(new Person("user",123));
list1.add(new Person("hello",123));
list1.add(new Person("linux",123));
Iterator<Person> iterator = list1.iterator();
//使用集合的删除的方法会出现并发修改异常
while (iterator.hasNext()){
Person next = iterator.next();
if("name".equals(next.getName())){
iterator.remove();
}
}
System.out.println(list1);
}
}
迭代器的另一种写法
for (Iterator<Person> iterator = list1.iterator(); iterator.hasNext();){
if(iterator.next().getName().equals("name")){
iterator.remove();
}
}
新式for循环删除(不能删除,只能遍历,依赖迭代器进行的遍历)
静态导入 jdk1.5 的新特性
导入类中的静态方法
import static java.util.Arrays.sort;
/**
* 静态导入
* @author kiosk
*/
public class Test6 {
public static void main(String[] args) {
int[] arr = {44,22,55,21};
sort(arr);
for (int i : arr) {
System.out.println(i);
}
}
}
可变参数
使用的具体的方法:
public class Test7 {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 4, 5};
print(1,222,33,444,4);
}
public static void print(int x, int... arr) {
for (int i : arr) {
System.out.println(i);
}
}
}
注意int … arr 如果在前面的话,就会把之前的参数吞掉
数组转为集合
不能添加元素会出现UnsupportedOperationException异常
/**
* 数组可以转为数组,虽然不能增加或者是减少元素。但是可以用集合的思想
* 来操作数组
* @author kiosk
*/
public class Test8 {
public static void main(String[] args) {
String[] strings = {"i", "love", "my", "country"};
List<String> list = Arrays.asList(strings);
list.add("hello world");
System.out.println(list);
}
}
集合中的嵌套
public class Test {
public static void main(String[] args) {
ArrayList<Person> group1 = new ArrayList<>();
group1.add(new Person("张三",17));
group1.add(new Person("李四",17));
group1.add(new Person("王五",17));
ArrayList<Person> group2 = new ArrayList<>();
group2.add(new Person("rose",12));
group2.add(new Person("jack",22));
group2.add(new Person("jackson",14));
ArrayList<Person> group3 = new ArrayList<>();
group3.add(new Person("java",20));
group3.add(new Person("linux",20));
group3.add(new Person("php",30));
ArrayList<ArrayList<Person>> arr = new ArrayList<>();
arr.add(group1);
arr.add(group2);
arr.add(group3);
for (ArrayList<Person> personArrayList : arr) {
for (Person person : personArrayList) {
System.out.println(person.getName() + "====" + person.getAge());
}
}
}
}