首先想到了ArrayList和List的区别:
1: List是一个接口,而ArrayList是List接口的一个实现类。
2:List接口不能被构造,也就是我们说的不能创建实例对象,但是我们可以像下面那样为List接口创建一个指向自己的对象引用,而ArrayList实现类的实例对象就在这充当了这个指向List接口的对象引用。
又想到了集合和数组的区别:
数组:这是java语言内置的数据类型,是一个线性序列,可以快速的访问其他元素,数据在你创建的那一刻就已经定好了容量,并且生命周期也是不能改变的,并且再java的异常机制中发现了数组越界会报错:RuntimeException
集合:java对于集合提供了三种集合:list,map,set,这些对象直接归根于object,他们处理对象的时候就好像这些对象没有自己的类型一样,这样只需要创建一个集合,把对象放进去,取出时转换成自己的类型就行了。
数组和集合的区别
数组是静态的,一个数组实例具有固定的大小,一旦创建了就无法改变容量了。而集合是可以动态扩展容量,可以根据需要动态改变大小,集合提供更多的成员方法,能满足更多的需求。
-
3、数组的存放的类型只能是一种(基本类型/引用类型),集合存放的类型可以不是一种(不加泛型时添加的类型是Object)。
-
4、数组是java语言中内置的数据类型,是线性排列的,执行效率或者类型检查都是最快的。
-
5、集合以接口和类的形式存在,具有封装,继承和多态等类的特性,通过简单的方法和属性调用即可实现各种复杂的操作,大大提高软件的开发效率。
List list;//正确,list = null;
List list = new List();//是错误的用法 这是错误的!!!!!
List list = new ArrayList();这句创建了一个ArrayList实现类的对象后把它上溯到了List接口。此时它就是一个List对
象了,它有些ArrayList类具有的,但是List接口没有的属性和方法,它就不能再用了。 而ArrayList list=newArrayList();
创建一对象则保留了ArrayList的所有属性和方法。
list,map,set的讲解:
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
首先通过这张图就可以看出来在Collection中包含了List和Set,Map是单独列出来的一个
然后是Collection:这是在用到ArrayList的时候发现有一个求最大的集合中的值用到了Collection,这里再讲解一下Collection接口:
1:Collection接口
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。
所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建一个空的Collection,有一个 Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection。
如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:
Iterator it = collection.iterator(); // 获得一个迭代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下一个元素
}
由Collection接口派生的两个接口是List和Set。
2.Set:不包含重复的元素!
Set接口同样是Collection接口的一个子接口,它表示数学意义上的集合概念。Set中不包含重复的元素,即Set中不存两个这样的元素e1和e2,使得e1.equals(e2)为true。由于Set接口提供的数据结构是数学意义上集合概念的抽象,因此它需要支持对象的添加、删除,而不需提供随机访问。故Set接口与Collection的接口相同。
-
1:Set接口继承Collection接口,而且它不允许集合中存在重复项。所有原始方法都是现成的,没有引入新方法。具体的Set实现类依赖添加的对象的equals()方法来检查等同性。
-
2:HashSet: 使用HashMap的一个集的实现。虽然集定义成无序,但必须存在某种方法能相当高效地找到一个对象。使用一个HashMap对象实现集的存储和检索操作是在固定时间内实现的.
-
3:TreeSet: 在集中以升序对对象排序的集的实现。这意味着从一个TreeSet对象获得第一个迭代器将按升序提供对象。TreeSet类使用了一个TreeMap.
Set的演示:
import java.util.*;
public class SetExample {
public static void main(String args[]) {
Set set = new HashSet();
set.add("Bernadine");
set.add("Elizabeth");
set.add("Gene");
set.add("Elizabeth");
set.add("Clara");
System.out.println(set);
Set sortedSet = new TreeSet(set);
System.out.println(sortedSet);
}
}
运行程序产生了以下输出。请注意重复的条目只出现了一次,列表的第二次输出已按字母顺序排序。
[Gene, Clara, Bernadine, Elizabeth]
[Bernadine, Clara, Elizabeth, Gene]
3.List:
1:List接口继承了Collection 接口以定义一个允许重复项的有序集合。该接口不但能够对列表的一部分进行处理,还添加了面向位置的操作。
2: 实际上有两种List: 一种是基本的ArrayList
,其优点在于随机访问元素,另一种是更强大的LinkedList
,它并不是为快速随机访问设计的,而是具有一套更通用的方法。
3:List : 次序是List最重要的特点:它保证维护元素特定的顺序。List为Collection添加了许多方法,使得能够向List中间插入与移除元素(这只推荐LinkedList使用。)一个List可以生成ListIterator
,使用它可以从两个方向遍历List,也可以从List中间插入和移除元素。
4:ArrayList : 由数组实现的List。允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢。ListIterator
只应该用来由后向前遍历ArrayList,而不是用来插入和移除元素。因为那比LinkedList
开销要大很多。
5:LinkedList : 对顺序访问进行了优化,向List中间插入与删除的开销并不大,随机访问则相对较慢。(使用ArrayList代替。)还具有下列方法:addFirst(), addLast(), getFirst(), getLast(), removeFirst() 和 removeLast(), 这些方法 (没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。
6: Vector:实现一个类似数组一样的表,自动增加容量来容纳你所需的元素。使用下标存储和检索对象就象在一个标准的数组中一样。你也可以用一个迭代器从一个Vector中检索对象。Vector是唯一的同步容器类!!当两个或多个线程同时访问时也是性能良好的。
7:Stsck: 这个类从Vector派生而来,并且增加了方法实现栈!一种后进先出的存储结构。
4.List和Set对比:
用到了ArrayList<Integer>中的一些方法:
1.添加元素:
//添加
ArrayList<Integer> list2 = new ArrayList<Integer>();
list2.add(12);
list2.add(23);
list2.add(9);
2:最大最小值
// get max,min
int maxa = Collections.max(list2),mina = Collections.min(list2);
System.out.println("list2's max value is " + maxa);
System.out.println("list2's min value is " + mina);
list2's max value is 23
list2's min value is 9
3.输出
//print
System.out.println("whole list2 is "+list2);
whole list2 is [12, 23, 9]
4.拷贝:
//拷贝
ArrayList<Integer> list21 = new ArrayList<Integer>();
list21.addAll(list2);
System.out.println("list21:copy list2 is "+list21);//不变
5.从小到大排序
Collections.sort(list2);
System.out.println("list2 sort is "+list2);
list2 sort is [9, 12, 23]
6.从大到小排序
Collections.sort(list2,Collections.reverseOrder());
System.out.println("list2 descend sort is "+list2);
list2 descend sort is [23, 12, 9]
7.倒序
Collections.reverse(list21);
System.out.println("reverse list21 is "+list21);
reverse list21 is [9, 23, 12]
8.求某个元素首次出现的位置
int idx = list2.indexOf(23);
System.out.println("list2 is "+list2+" and 23 locates :"+idx);
list2 is [23, 12, 9] and 23 locates :0
9.求和
int sum = 0;
for (int i=0;i<list2.size();i++){
sum += list2.get(i);
}
System.out.println("list2 sum is "+sum);
//利用stream求和
List<Integer> ls = new ArrayList<Integer>();
ls.add(43);
ls.add(27);
int sum2 = ls.stream().mapToInt(a->a).sum();
System.out.println("sum is "+sum2);
list2 sum is 44
sum is 70
10.在指定位置插入元素
//在1位置插入一个88(like insert)
list2.add(1,88);
System.out.println("insert 88 at [1] and list2 is "+list2);
insert 88 at [1] and list2 is [23, 88, 12, 9]
11.移除某个位置的元素
list2.remove(1);
System.out.println("remove [1] and list2 is "+list2);
list2.remove(list2.size()-1);//删除末尾
System.out.println("remove the last and list2 is "+list2);
remove [1] and list2 is [23, 12, 9]
remove the last and list2 is [23, 12]
12.移除某个值:
list2.add(0,23);
System.out.println("add 23 at [0] and list2 now is "+list2);
for (int i=0;i<list2.size();i++){
if (list2.get(i)==23){
list2.remove(i);
i--;
}
}
System.out.println("remove 23 and list2 is "+list2);
remove 23 and list2 is [12]
13.切片
ArrayList<Integer> list3 = new ArrayList<Integer>();
list3.add(45);
list3.add(52);
list3.add(66);
System.out.println("list3 is "+list3);
System.out.println("list3[0:2] is "+list3.subList(0,2));
list3 is [45, 52, 66]
list3[0:2] is [45, 52]
14.转化为整形数组
import java.util.*;
class Solution {
public int[] twoSum(int[] nums, int target) {
ArrayList<Integer> re = new ArrayList<Integer>();
for (int i=0;i<nums.length;i++){
for (int j=i+1;j<nums.length;j++){
if (nums[i]+nums[j]==target){
re.add(i);
re.add(j);
}
}
}
int[] res = re.stream().mapToInt(Integer::valueOf).toArray();
return res;
}
// 调用
public static void main(String[] args){
int[] nums = {2,7,11,9};
int target = 9;
Solution s = new Solution();
int[] lst = s.twoSum(nums,target);
System.out.println(Arrays.toString(lst));
}
}
[0, 1]