Java集合---List(线性表)

时间:2022-05-30 17:53:10

List接口是Collection的子接口,用于定义线性表数据结构。可以将List理解为存放对象的数组,只不过其元素个数可以动态的增加或减少。

List接口的两个常见实现类为ArrayList和LinkedList,分别用动态数组和链表的方式实现了List接口。

1、基本操作

import java.util.ArrayList;
import java.util.List;

/**
* java.util.List
* 可重复集,并且有序。
* 特点是可以根据下标操作元素。
* 常用实现类:
* ArrayList: 使用数组实现,查询更快
* LinkedList: 使用链表实现,增删更快(首尾增删效果明显)
*/

public class ListDemo1 {

public static void main(String[] args) {
/*
* E set(int index, E e)
* 将给定元素设置到指定位置上,返回值为原位置的元素。所以是替换元素操作。
*/

List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
//[one, two, three, four]
System.out.println(list);

//[one, 2, three, four]
String old = list.set(1, "2"); //返回的是原先那个位置的值
System.out.println(list);
System.out.println("old: "+old);

//[one, 2, three, four, five]
//list.set(4,"five"); 这样做下标越界

/*
* E get(int index)
* 获取给定下标对应的元素
*/

//获取第三个元素
String str = list.get(2);
System.out.println(str);

for(int i=0; i<list.size(); i++){
str = list.get(i);
System.out.println(str);
}


}

}

import java.util.ArrayList;
import java.util.List;

/**
* List集合提供了一对重载的add, remove方法
* void add(int index, E e)
* 将给定元素插入到指定位置,原位置及后续元素都顺序向后移动
*
* E remove(int index)
* 从集合中删除指定位置的元素,并将其返回
*/

public class ListDemo2 {

public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
//[one, two, three, four]
System.out.println(list);

//[one, 2, two, three, four]
list.add(1, "2");
System.out.println(list);

//[one, 2, three, four]
String old = list.remove(2);
System.out.println(list);
System.out.println("old: "+old);
}

}

import java.util.ArrayList;
import java.util.List;
/**
* 取子集
* List subList(int start, int end)
* 获取当前集合中指定范围内的子集。同样含头不含尾
* 需要注意的是,subList获取的List与原List占有相同的存储空间,对子List的操作会影响原List.
*/

public class ListDemo3 {

public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
for(int i=0; i<10; i++){
list.add(i);
}
System.out.println(list);

//获取3-7
List<Integer> subList = list.subList(3, 8);
System.out.println(subList);

//将子集中的每个元素扩大10倍
for(int i=0; i<subList.size(); i++){
int n = subList.get(i);
n *= 10;
subList.set(i, n);
}
//[30, 40, 50, 60, 70]
System.out.println(subList);
/*
* 对子集的修改,就是修改原集合相应内容
*/

//[0, 1, 2, 30, 40, 50, 60, 70, 8, 9]
System.out.println(list);

/*
* 删除集合中2-8的元素
*/

list.subList(2, 9).clear();
System.out.println(list);

}

}

2、集合与数组互相转换

2.1 集合转换为数组

import java.util.ArrayList;
import java.util.Collection;

public class CollectionToArrayDemo {

public static void main(String[] args) {
Collection<String> c = new ArrayList<String>();
c.add("one");
c.add("two");
c.add("three");
c.add("four");

/* 方法一: Object[] toArray()
* 集合提供了一个方法toArray,可以将当前集合转换为数组 .
* 该方法得到的是Object类型的数组,使用时不方便,所以该方法不怎么使用了
*/

//Object[] array = c.toArray();


/* 方法二: <T>T[] toArray(T[] a)
* 若给定的数组可用(数组可以存放集合所有元素)时,则使用该数组,
* 若不可用,会自动创建一个与给定数组同类型的数组 。
*/

String[] array = c.toArray(new String[c.size()]);

for(String str : array){
System.out.println(str);
}

}

}

2.2 数组转换为集合

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* 数组转换为集合
* 需要注意,转换只能转换为List集合
* 使用的是数组的工具类Arrays的静态方法asList
* 只能转换List集合的主要原因是:Set不能存放重复元素。
* 所以若转换为Set集合可能出现丢失元素的情况。
*/

public class ArrayToListDemo {

public static void main(String[] args) {
String[] array = {"one","two","three","four"};

List<String> list = Arrays.asList(array);
System.out.println(list);

/*
* 向集合中添加一个元素
* 实际上下面的代码会抛出异常。原因在于,该集合是由数组转换过来的,
* 那么该集合就表示原来的数组,所以对集合的操作就是对数组的操作。
* 那么新添加元素会导致原数组扩容,(数组是定长的),那么久不能表示原来的数组了。
* 所以不允许向该集合添加新元素。
*/

//list.add("five");
//System.out.println(list);

//修改集合元素,数组元素也会改变
list.set(1,"2");
System.out.println(list);
//输出数组元素
for(String str : array){
System.out.println(str);
}

/*
* 若希望增删元素,需要另创建一个集合 !!!
*/

// List<String> list1 = new ArrayList<String>();
// list1.addAll(list);
/*
* 所有的集合都提供了一个带有Collection类型参数的构造方法。
* 该构造方法称为:复制构造器
* 作用是在创建当前集合的同时,集合中包含给定集合中的所有元素。
*/

List<String> list1 = new ArrayList<String>(list);
list1.add("five");
System.out.println(list1);


}

3、List的排序

3.1 基本排序

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

/**
* 排序集合元素
* 排序集合使用的是集合的工具类Collections的静态方法sort.
* 排序仅能对List集合进行,因为Set部分实现类是无序的。
*/

public class SortListDemo {

public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();

Random random = new Random();

for(int i=0; i<10; i++){
list.add(random.nextInt(100));
}

System.out.println(list);
/*
* 对集合进行自然排序,从小到大
*/

Collections.sort(list);
System.out.println(list);

}

}

3.2 自定义排序(方式一)

/**
* 该类用于作为集合的元素
*/

public class Point implements Comparable<Point>{
private int x;
private int y;

public Point(int x, int y) {
super();
this.x = x;
this.y = y;
}

public int getX() {
return x;
}

public void setX(int x) {
this.x = x;
}

public int getY() {
return y;
}

public void setY(int y) {
this.y = y;
}

@Override
public String toString() {
return "(" + x + "," + y + ")";
}

/*
* 当实现了Comparable接口后,需要重写下面的方法,
* 该方法的作用是定义当前对象与给定参数对象比较大小的规则。
* 返回值为一个int值,该值表示大小关系。它不关注具体的取值是多少,而关注的是取值范围。
* 当返回值>0时:当前对象比参数对象大
* 当返回值<0时:当前对象比参数对象小
* 当返回值=0时:两个对象相等。
*/

@Override
public int compareTo(Point o) {
/*
* 比较规则,点到原点的距离长的大
*/

int len = this.x*this.x + this.y*this.y;
int olen = o.x*o.x + o.y*o.y;
return len-olen;
}


}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* 排序自定义类型元素的集合
*/

public class SortListDemo1{

public static void main(String[] args) {
List<Point> list = new ArrayList<Point>();

list.add(new Point(4,2));
list.add(new Point(2,3));
list.add(new Point(1,4));
list.add(new Point(6,7));
list.add(new Point(9,3));
list.add(new Point(8,1));

System.out.println(list);
/*
* sort方法要求集合元素必须实现Comparable接口,该接口用于规定实现类是可以比较的。
* 其中有一个抽象方法是用来定义比较大小的规则。
*
* 我们想使用sort方法排序集合,但是该方法要求我们的集合元素必须实现Comparable接口
* 并且定义比较规则,这种我们想使用某个功能,而它要求我们修改程序的现象称为“侵入性”。
* 修改的代码越多,侵入性越强,月不利于程序的扩展。
*/

Collections.sort(list);
System.out.println(list);

}


}

3.3 自定义排序(方式二)

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class SortListDemo2 {

public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("jerry");
list.add("tom");
list.add("merry");
list.add("rose");
list.add("jack");
list.add("kobe");
list.add("JACKSON");
list.add("JAMES");
System.out.println(list);
Collections.sort(list);
System.out.println(list);

MyComparator com = new MyComparator();
/*
* 重载的sort方法要求传入一个额外的比较器
* 该方法不再要求集合元素必须实现 Comparable接口,
* 并且也不再使用集合元素自身的比较规则排序了,而是
* 根据给定的这个额外的比较器的比较规则对集合元素进行排序。
* 实际开发中也推荐使用这种方式排序集合元素,若集合元素是自定义的。
* 创建比较器时也推荐使用匿名内部类的形式。
*/

Collections.sort(list, com);
System.out.println(list);

//匿名内部类形式创建
Comparator<String> com1 = new Comparator<String>(){
public int compare(String o1, String o2) {
return o2.length()-o1.length();
}
};
Collections.sort(list, com1);
System.out.println(list);

}

}

/**
* 定义一个额外的比较器
*/

class MyComparator implements Comparator<String>{
/*
* 改方法用来定义o1和o2的比较
* 若返回值>0: o1>o2
* 若返回值<0: o1<o2
* 若返回值=0: 两个对象相等
*/

public int compare(String o1, String o2) {
/*
* 字符串中字符多的大
*/

return o1.length()-o2.length();
}

}

参考文献:

说明:代码来源于达内教育