一、list概述
1、list接口概述
List接口继承自Collection接口,是单列集合的一一个重要分支,我们习惯性地会将实现了
List接口的对象称为List集合。在List集合中允许出现重复的元素,所有的元素是以一种线性方
式进行有序存储的,在程序中可以通过索弓|来访问集合中的指定元素。
2、list接口的特点
有序可重复 有索引 可以判断重复
➢它是一个元素存取有序的集合。例如,存元素的顺序是11、22、33。那么集合中,元素的
存储就是按照11、22、 33的顺序完成的)。, 有序重复
➢它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个
道理) 有索引
➢集合中可以有重复的元素
,通过元素的equals方法,来比较是否为重复的元素。
3、ArryList常用的接口方法
List作为Collection集合的子接口,不但继承了Collection接口中的全部方法,而且还增加
了一些根据元素索引来操作集 合的特有方法。
1、将指定的元素,添加到该集合中的指定位置上
public void add(int index, E element);
2、返回集合中指定位置的元素
public E get(int index) ;
3、移除列表中指定位置的元素,返回的是被移除的元素
public E remove(int index) ;
4、用指定元素替换集合中指定位置的元素,返回值的更新前
public E set(int index, E element) :
5、返回列表中指定的fromIndex (包括)和tolndex (不包括)之间的部分内容
public List<E> subList(int fromIndex, int tolndex):
6、找到集合中这个元素的下标位置
public int indexOf(Object o):
二 、list demo
/**
*
* List接口里面方法的基本操作
* 1、List是有序且重复的,并且带索引的接口
* 2、List的常见方法的演示
* 3、list里面的remove方法,有两个方法的重载,分别是参数是int类型的index
* 和参数是Object类型的对象,那么如果是一个Integer作为泛型的集合对象的话,你
* 写的是整型,那么它会调用哪个方法呢?
* 这里就必须要理解,此时它不需要自动装箱就能调用方法的话,它就不会去进行自动装箱
* 所以,会调用参数是int类型的index的方法;
*
*/
public class ListDemo {
public static void main(String[] args) {
//构建一个List对象
List<String> list = new ArrayList<String>();
list.add("中国");
list.add("美国");
list.add("俄罗斯");
//带下标的add方法,下标就是你想要放入的位置的下标
list.add(1, "德国");
list.add("德国");
list.add(null);
System.out.println(list);
//list接口下的其他方法
//get方法
System.out.println(list.get(1));
//indexOf
System.out.println(list.indexOf("美国"));
//subList
System.out.println(list.subList(1, 3));
//set
list.set(list.size()-1, "日本");
System.out.println(list);
//remove
list.remove(list.size()-1);
System.out.println(list);
list.remove("德国");
//请问,如果list集合中存在重复的元素,那么remove会都删掉吗?
System.out.println(list);//只会删除第一个查找到的元素
List<Integer> list1 = new ArrayList<Integer>();
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.remove(1);//请问,这个1是object还是index
System.out.println(list1);
}
}
三、list 的接口实现类
1、ArryList
ArrayList类的底层存储结构是数组结构
。
可以直接通过下标来很迅速的找到指定下标的元素来进行操作,
所以ArrayList在操作指定下标的任意元素上面,速度比较快。
注意:
日常开发中程序员会习惯使用ArrayList来解决所有集合的问题
,但是一定要注意,
它的底层是数组的特点决定于它只是查找上以及指定下标操作。上速度快。
2、LinkedList
底层是双向链表,既然底层是双向链表,所以我们在使用LinkedList来操作对象的时候,首
部和尾部元素的操作速度比较快。
3、Vector
ArrayList类出现之前的版本,ArrayList出现之后, 就不再使用Vector了,它和ArrayList的
区别,基本等同于StringBuffer和StringBuilder的区别。
四、LinkedList
只要涉及到首尾操作频繁的容器,就去找LinkedList的API方法即可,否则,只管用ArrayList。
public class LinkedListDemo {
public static void main(String[] args) {
//List接口的特点,在这里得到了体现:有序、重复,可以为null
LinkedList<String> list = new LinkedList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add(null);
list.add("aaa");
System.out.println(list);
//进行LinkedList里面的API方法的操作
//添加到首部、尾部
list.addFirst("kkk");
System.out.println(list);
list.addLast("zzz");
System.out.println(list);
//获取到首部和尾部的元素
System.out.println(list.getFirst());
System.out.println(list.getLast());
//删除首部和尾部的元素
list.removeFirst();
System.out.println(list);
list.removeLast();
System.out.println(list);
//弹栈:栈这个数据结构:堆柴火
while(!list.isEmpty()) {
//把集合顶部的元素弹出来
System.out.println(list.pop());
}
System.out.println(list);
}
}
五、单向链表
原理:
多个结点之间,通过地址进行连接。例如,多个人手拉手,
每个人使用自己的右手拉住下个人的左手,依次类推,这样多个
人就连在一起了。
特点:
查找元素慢,增删元素快。
/**
*
* 演示单向链表
* 所谓单向链表我们可以看成是多个环扣在一起,但是只能作用第一个环,一旦你作用了第一个
* 环,那么就会直接影响到剩下的所有环,这里是不允许你操作最后一个环的,因为双向链表就是
* 可以允许你首尾都操作
*
*/
public class SingleLinkedListDemo {
public static void main(String[] args) {
//创建一个首部节点
Node head = new Node("黑桃A");
//在当前节点上构建下一个节点对象
head.next = new Node("红桃J");
//继续往下面构建节点
head.next.next = new Node("梅花3");
head.next.next.next = new Node("方块8");
System.out.println(head);
}
}
class Node{
//定义一个Object类型的属性,用来为每个环起名字
Object value;
//既然每个环可以操作下一个环,那么我们是否可以认为,每个环拥有下个环对象
Node next;
//创建一个有参的构造函数
public Node(Object value) {
this.value = value;
}
//重写toString方法,方便我们来看到整体的结构
@Override
public String toString() {
return next==null?value.toString():value.toString()+next.toString();
}
}
六、链表内存图例
七、arraylist和linkedlist 运行方式比较
八、demo
千千静听播放列表(控制台版)
a、写一个song类, 里面有歌名和歌手
b、写一个demo类,使用集合为容器,往里面插入一些歌曲
C、然后来进行一个人性化的操作,里面有查看、追加、查找、删除、删除全部、退出等功能
d、要求,各个操作尽量的人性化
附加功能:如何才能真正的播放出音乐呢?
public class Song {
private String songName;
private String songAuthor;
public Song() {
}
public Song(String songName, String songAuthor) {
super();
this.songName = songName;
this.songAuthor = songAuthor;
}
public String getSongName() {
return songName;
}
public void setSongName(String songName) {
this.songName = songName;
}
public String getSongAuthor() {
return songAuthor;
}
public void setSongAuthor(String songAuthor) {
this.songAuthor = songAuthor;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((songAuthor == null) ? 0 : songAuthor.hashCode());
result = prime * result + ((songName == null) ? 0 : songName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Song other = (Song) obj;
if (songAuthor == null) {
if (other.songAuthor != null)
return false;
} else if (!songAuthor.equals(other.songAuthor))
return false;
if (songName == null) {
if (other.songName != null)
return false;
} else if (!songName.equals(other.songName))
return false;
return true;
}
@Override
public String toString() {
return "<"+songName+"_"+songAuthor+">";
}
}
public class SongDemo {
public static void main(String[] args) {
ArrayList<Song> songs = initSongs();
//输出欢迎语句
System.out.println("欢迎使用XXXX播放器");
//创建一个Scanner对象
Scanner sc = new Scanner(System.in);
//设置一个死循环
while(true) {
System.out.println("请输入你要进行的操作:1.查看;2.追加;3.查找;4.删除;5.删除所有;6.退出");
int order = sc.nextInt();
boolean flag =false;
switch(order) {
case 1:
if(songs.isEmpty()) {
System.out.println("你的播放列表为空");
}else {
System.out.println(songs);
}
;break;
case 2:
System.out.println("请输入你要添加的歌曲名和歌手名:");
String songName = sc.next();
String songAuthor = sc.next();
Song newSong = new Song(songName,songAuthor);
if(songs.contains(newSong)) {
System.out.println("您的播放列表中已经存在该歌曲,是否要继续添加进列表?(1为添加,2为不添加)");
int newOrder = sc.nextInt();
if(newOrder==1) {
songs.add(newSong);
System.out.println("歌曲添加成功!");
}
}else {
songs.add(newSong);
System.out.println("歌曲添加成功!");
}
;break;
case 3:
System.out.println("请输入您要查找的歌手名:");
String author = sc.next();
//定义一个集合,用来放查找到的Song对象的
ArrayList<Song> newList = new ArrayList<Song>();
for(Song s:songs) {
if(s.getSongAuthor().equals(author)) {
newList.add(s);
}
}
if(newList.isEmpty()) {
System.out.println("对不起,您要查找的歌手没有对应的数据");
}else {
System.out.println(newList);
}
;break;
case 4:
System.out.println("请输入您要删除的歌曲名和歌手名:");
String songName1 = sc.next();
String songAuthor1 = sc.next();
Song newSong1 = new Song(songName1,songAuthor1);
if(songs.contains(newSong1)) {
//如果没有重写equals方法的话那么这里就会出问题
songs.remove(newSong1);
System.out.println("删除成功!");
}else{
System.out.println("对不起,您要删除的歌曲不存在!");
}
;break;
case 5:
System.out.println("你确定要删除所有歌曲吗?(1.确定;2.考虑下)");
int order1 = sc.nextInt();
if(order1==1) {
songs.clear();
System.out.println("删除成功!");
}
;break;
case 6:
System.out.println("你确定要退出那么好玩的游戏吗?(1.确定;2.考虑下)");
int order2 = sc.nextInt();
if(order2==1) {
System.out.println("欢迎下次继续来使用本软件,够的败!");
flag = true;
}
;break;
default:System.out.println("您所输入的指令不正确,请重新输入!");
}
if(flag) {
break;
}
}
}
//初始化一个有歌曲的播放器
public static ArrayList<Song> initSongs(){
ArrayList<Song> songs = new ArrayList<Song>();
songs.add(new Song("忘情水","刘德华"));
songs.add(new Song("练习","刘德华"));
songs.add(new Song("饿狼传说","张学友"));
return songs;
}
}