【JavaSE】day05_List集合_List排序_队列和栈
1.List集合
1)有序集,可重复集。List的特点是可以像数组一样,根据下标操作元素。所以List提供了一些独有的方法。
2)常用实现类:
--ArrayList:内部由数组实现,查询快。
--LinkedList:内部由链表实现,增删快。
3)E get(int index)
获取指定下标对应的元素。(下标从0开始)
4)E set(int index,E e)
将给定的元素设置到指定的位置上,返回值为原位置上的元素。所以该操作是替换元素操作。
注:需在现有的元素上进行操作。
代码演示:
package day04;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* List集合
* 有序集,可重复集。
* List的特点是可以像数组一样,根据下标操作元素。
* 所以List提供了一些独有的方法。
* 常用实现类:
* ArrayList:内部由数组实现,查询快。
* LinkedList:内部由链表实现,增删快。
*
*/
public class ListDemo01 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
/*
* E get(int index)
* 获取指定下标对应的元素。(下标从0开始)
*/
String str = list.get(0);
System.out.println(str); //one
//遍历全部元素
//1.
for(int i=0;i<list.size();i++){ //size()来获取容器元素个数
str = list.get(i);
System.out.println(str);
}
//2.
Iterator<String> it = list.iterator();
while(it.hasNext()){
str = it.next();
System.out.print(str+" ");
}
System.out.println();
/*
* E set(int index,E e)
* 将给定的元素设置到指定的位置上,返回值为原位置
* 上的元素。所以该操作是替换元素操作。
* 注:需在现有的元素上进行操作。
*/
//[one,2,three,four]
String old = list.set(1,"2");
System.out.println(list);
System.out.println("被替换掉的元素为:"+old);
list.add(2,"###");
list.add(5,"1");
System.out.println(list);
}
}
5)void add(int index,E e)
向指定位置插入给定元素,原位置及后续元素顺序向后移动。
6)E remove(int index)
删除并返回给定位置的元素。
代码演示:
package day04;
import java.util.LinkedList;
import java.util.List;
/**
* List提供的另一对方法:
* void add(int index,E e)
* 向指定位置插入给定元素,原位置及后续元素顺序向后移动。
*
* E remove(int index)
* 删除并返回给定位置的元素。
*
*/
public class ListDemo02 {
public static void main(String[] args) {
List<String> list = new LinkedList<String>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
System.out.println(list); //[one, two, three, four]
//[one, two, 3, three, four]
list.add(2,"3");
System.out.println(list); //[one, two, 3, three, four
//[one, two, 3, three, four, 5]
//在末尾追加一个
list.add(5,"5");
System.out.println(list); //[one, two, 3, three, four, 5]
//[one, two, 3, four, 5]
String old = list.remove(3); //下标不能越界
System.out.println(list); //[one, two, 3, four, 5]
System.out.println("被删除的元素是:"+old); //three
System.out.println(list.get(3));
}
}
7)List subList(int start,int end)
获取当前集合中给定范围内的部分子集
对子集的任何操作都会影响原集合。
清空子集,原集合中该部分内容也被删除。通过清空子集来快速删除原集合的指定内容。
代码演示:
package day04;
import java.util.ArrayList;
import java.util.List;
/**
* 获取List集合中的子集
*
*/
public class ListDemo03 {
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); //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
/*
* List subList(int start,int end)
* 获取当前集合中给定范围内的部分子集
*/
List<Integer> subList = list.subList(3,8);
System.out.println(subList); //[3, 4, 5, 6, 7]
//将子集中的每个元素扩大10倍
for(int i=0;i<subList.size();i++){
/*int n = subList.get(i);
n = n*10;
subList.set(i,n);*/
subList.set(i,subList.get(i)*10);
}
System.out.println(subList); //[30, 40, 50, 60, 70]
/*
* 对子集的任何操作都会影响原集合。
*/
System.out.println(list); //[0, 1, 2, 30, 40, 50, 60, 70, 8, 9]
//清空子集,原集合中该部分内容也被删除。
//通过清空子集来快速删除原集合的指定内容。
subList.clear();
System.out.println(list); //[0, 1, 2, 8, 9]
}
}
8)集合转换成数组
Collection中提供了一个方法toArray,允许我们将现有的集合转换为数组。
代码演示:
package day04;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
/**
* 集合转换成数组
* Collection中提供了一个方法toArray
* 允许我们将现有的集合转换为数组。
*
*/
public class ColletionToArray {
public static void main(String[] args) {
Collection<String> c = new ArrayList<String>();
c.add("one");
c.add("two");
c.add("three");
c.add("four");
String[] array = c.toArray(new String[c.size()]);
System.out.println(Arrays.toString(array)); //[one, two, three, four]
array[0]="1";
System.out.println(Arrays.toString(array)); //[1, two, three, four]
System.out.println(c); //[one, two, three, four]
c.add("##");
System.out.println(Arrays.toString(array)); //[1, two, three, four]
System.out.println(c); //[one, two, three, four, ##]
/*
* 总结:当把集合转化成数组后,可以对集合中的元素进行增删改查操作
* 两者之间互不影响。
* 当集合中存的是对象时,当改变对象中的属性的值时,都会跟着改变。
*/
}
}
9)数组转换成集合
使用Arrays的静态方法asList()需要注意,数组只能转换为List集合,不能转换成Set。原因:
* 1.Set大部分是无序实现
* 2.Set不允许存放重复元素,所以转换后可能丢失元素。
对于由数组转换的集合来说,添加元素是不受支持的!
代码演示:
package day04;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 数组转换成集合
* 使用Arrays的静态方法asList()
* 需要注意,数组只能转换为List集合,不能转换成Set。
* 原因:
* 1.Set大部分是无序实现
* 2.Set不允许存放重复元素,所以转换后可能丢失元素。
*
*/
public class ArrayToList {
public static void main(String[] args) {
String[] array = new String[]{"one","two","three"};
List<String> list = Arrays.asList(array);
System.out.println(list); //[one, two, three]
/*
* 修改该集合元素内容,原数组内容也会发生改变
*/
list.set(0,"1");
System.out.println(list); //[1, two, three]
//数组第一个元素也变为了"1"
System.out.println(Arrays.toString(array)); //[1, two, three]
array[2] = "222";
System.out.println(list); //[1, two, 222]
System.out.println(Arrays.toString(array)); //[1, two, 222]
/*
* 对于由数组转换的集合来说,添加元素是不受支持的!
* 所以下面代码会抛异常。
* java.lang.UnsupportedOperationException
*/
//list.add("four");
//System.out.println(list); //报错
/*
* 数组->集合总结:
* 1.只能对集合元素进行修改操作,不能删除和增加
* 2.对数组或集合中的元素进行修改时,会影响另一个。
* 3.如果想对集合进行增删操作,可以新new一个集合。
*/
/*
* 所有的集合都支持一个构造方法,参数要求传入另一个集合。
* 这个构造方法的作用是:
* 创建当前集合的同时将给定的集合中的所有元素添加到当前集合中。
* 创建后的新集合的任何操作与原集合无关。对原集合无影响。
*/
List<String> list1 = new ArrayList<String>(list); //复制
//list1.addAll(list);
list1.add("22");
list1.set(1,"##");
System.out.println(list1);
System.out.println(list);
}
}
2.List排序
1)Collections:集合的工具类
该类提供了若干静态方法,可以方便操作集合。其中sort方法是用来排序List集的。进行自然排序(从小到大)。
代码:
package day05;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
/**
* Collections:集合的工具类
* 该类提供了若干静态方法,可以方便操作集合。
* 其中sort方法是用来排序List集的。进行自然排序(从小到大)
*
*/
public class SortDemo01 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
Random rand = new Random();
for(int i=0;i<10;i++){
list.add(rand.nextInt(100));
}
System.out.println(list);
/*
* sort会对给定的List集合中的元素进行自然排序
* 即:从小到大的顺序
*
* 面试题:
* Collection与Collections的区别?(或分别说说它们)
*
*
*/
Collections.sort(list);
System.out.println(list);
}
}
2)Comparable接口
2.1) Collections的sort方法若希望对集合进行排序,必须保证集合中的元素是可比较大小的。
所以要求元素必须实现Comparable接口,并重写其中的比较大小方法(CompareTo方法),才能进行排序。
2.2)CompareTo方法的作用是使当前对象与给定的对象o进行比较大小。返回值不关注具体值,而是关注取值范围:
* 当返回值>0:当前对象比参数对象大
* 当返回值<0:当前对象比参数对象小
* 当返回值=0:两对象相等
2.3)当前元素若希望可以比较大小,需要实现Comparable接口,Comparable支持泛型,而泛型的实际类型就是当前类。意思就是,哪个类实现实现Comparable接口,泛型就是哪个类。
代码演示:
package day05;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class SortDemo02 {
public static void main(String[] args) {
List<Point> list = new ArrayList<Point>();
//Random rand = new Random();
//for(int i=0;i<5;i++){
// list.add(new Point(rand.nextInt(10),rand.nextInt(10)));
//}
list.add(new Point(1,2));
list.add(new Point(7,9));
list.add(new Point(5,4));
System.out.println(list); //[(1,2), (7,9), (5,4)]
/*
* Collections的sort方法若希望对集合进行排序,必须保证集合
* 中的元素是可比较大小的。
* 所以要求元素必须实现Comparable接口,并重写其中的
* 比较大小方法,才能进行排序。
*/
Collections.sort(list);
System.out.println(list); //[(1,2), (5,4), (7,9)]
/*
* 虽然sort方法可以对集合中的元素进行自然排序
* 但必须要求元素实现Comparable接口,这就出现
* 了由于想使用排序功能而必须改变我们定义的类的
* 内容,这种现象称为“侵入性”。
*/
}
}
3)Collections的重载sort方法:
要求我们传入两个参数:1:待排序的集合 2:比较器
3.1)通常有两种情况会使用该方法排序集合:
* 1:元素已经实现了Comparable接口,但是比较大小的规则不能满足我们对排序的需求。
* 2:元素没有实现Comparable接口,并且也不希望为了这里排序而强制修改元素,要求其实现接口。
3.2)匿名内部类的方式实现Comparator接口
代码演示:
package day05;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* Collections的重载sort方法
*
*/
public class SortDemo03 {
public static void main(String[] args) {
/*
* 字符串String实现了Comparable接口
* 排序规则:按照首字母的编码比大小。
*/
List<String> list = new ArrayList<String>();
list.add("苍老所");
list.add("小泽老师");
list.add("范老师");
list.add("小老师");
System.out.println(list); //[苍老所, 小泽老师, 范老师, 小老师]
/*
* Collections的重载sort方法要求我们传入两个参数:
* 1:待排序的集合
* 2:比较器
*
* 通常有两种情况会使用该方法排序集合:
* 1:元素已经实现了Comparable接口,但是比较大小的
* 规则不能满足我们对排序的需求。
* 2:元素没有实现Comparable接口,并且也不希望为了
* 这里排序而强制修改元素,要求其实现接口。
*
*/
//外部类的方式实现Comparator接口
//MyComparator com = new MyComparator();
//Collections.sort(list,com);
//匿名内部类的方式实现Comparator接口
Collections.sort(list,new Comparator<String>(){
@Override
public int compare(String o1, String o2) {
return o1.length()-o2.length();
}
});
/*Comparator<String> comp = new Comparator<String>(){
@Override
public int compare(String o1, String o2) {
return 0;
}
};*/ //匿名内部类
System.out.println(list); //[苍老所, 范老师, 小老师, 小泽老师]
}
}
class MyComparator implements Comparator<String>{
@Override
public int compare(String o1, String o2) {
return o1.length()-o2.length();
}
}
3.队列和栈
1)队列(Queue)
保存一组元素,但是对于存取有要求,必须遵循先进先出原则。
1.1)boolean offer(E e)
向队列末尾追加一个元素
1.2)E poll()
从队首获取元素。注意,获取后该元素就从队列中被移除类! 出队操作。
1.3)E peek()
同样可以获取队首元素,但是与poll不同的是不会将该元素从队列中删除。
具体细节见代码:
package day05;
import java.util.LinkedList;
import java.util.Queue;
/**
* 队列
* 保存一组元素,但是对于存取有要求,必须遵循
* 先进先出原则
*
*
*/
public class QueueDemo {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<String>();
/*
* boolean offer(E e)
* 向队列末尾追加一个元素
*/
queue.offer("one");
queue.offer("two");
queue.offer("three");
queue.offer("four");
System.out.println(queue); //[one, two, three, four]
/*
* E poll()
* 从队首获取元素。注意,获取后该元素就从队列
* 中被移除类! 出队操作
*/
String str = queue.poll();
System.out.println(str); //one
System.out.println(queue); //[two, three, four]
/*
* E peek()
* 同样可以获取队首元素,但是与poll不同的是
* 不会将该元素从队列中删除。
*/
str = queue.peek();
System.out.println(str); //two
System.out.println(queue); //[two, three, four]
//队列遍历
//1.
for(int i=0;i<queue.size();i++){
String str1 = queue.poll();
System.out.println(str1);
}
//原因:每执行一次for循环,queue.size()就会减一
System.out.println(queue); //[four]
//1.2 改进--倒着
for(int i=queue.size();i>0;i--){
String str1 = queue.poll();
System.out.println(str1);
}
System.out.println(queue); //[]
//2.--while循环--推荐
while(queue.size()>0){
String str1 = queue.poll();
System.out.println(str1);
}
System.out.println(queue); //[]
}
}
2)栈(Stack)
存储一组元素,存取必须遵循先进后出原则。
2.1)Deque(双端队列)是Queue的子接口。
双端队列的特点:队列的两端都可以进出元素。若我们只调用一侧的进出方法,就形成了栈结构。
2.2)void push(E e)
将元素“压入”栈中,入栈操作。新入栈的元素会在栈顶(栈中第一个元素).
2.3)E pop()
出栈操作,获取栈顶元素,获取后该元素就从栈中被删除了。
2.4)同样可以使用peek()引用栈顶元素,而不做出栈操作。
代码演示:
package day05;
import java.util.Deque;
import java.util.LinkedList;
/**
* 栈:存储一组元素,存取必须遵循先进后出原则。
* 通常用来实现有“后退”功能的地方。
*
*/
public class StackDemo {
public static void main(String[] args) {
/*
* Deque是Queue的子接口。
* 双端队列的特点:队列的两端都可以进出元素。
* 若我们只调用一侧的进出方法,就形成了栈结构。
*
*/
Deque<String> stack = new LinkedList<String>();
/*
* void push(E e)
* 将元素“压入”栈中,入栈操作。
* 新入栈的元素会在栈顶(栈中第一个元素).
*/
stack.push("one");
stack.push("two");
stack.push("three");
System.out.println(stack); //[three, two, one]
//stack.offerLast("#");
//System.out.println(stack);
/*
* E pop()
* 出栈操作,获取栈顶元素,获取后该
* 元素就从栈中被删除了。
*/
String str = stack.pop();
System.out.println(str); //three
System.out.println(stack); //[two, one]
/*
* 同样可以使用peek()引用栈顶元素,
* 而不做出栈操作。
*/
str = stack.peek();
System.out.println(str); //two
System.out.println(stack); //[two, one]
/*
* 遍历,和Queue相同
*/
while(stack.size()>0){
System.out.println(stack.pop());
}
System.out.println(stack); //[]
//System.out.println(stack.poll());
//System.out.println(stack.poll());
}
}
注:LinkedList实现了List<E>, Deque<E>接口