集 合
所学容器:数组、字符串缓冲区
对象数组:Student[] student = {s1,s2,s3};
——增删数组中元素
Student[] student =Arrays.copyOf(students,2);//删第三个元素
——数组作为容器,可以存储多种多样的类型,但是数组作为容器,增删数组中的元素是很不方便的,so,Java为了更方便 去操作容器中的元素**(增删改查)**,提供了另外一个容器:集合
数组和集合的区别
——数组:可以存储基本数据类型,也可存储引用数据类型
——集合:只能存储引用数据类型
——数组:一旦定义,长度不可变
——集合:长度可变
——数组:只能存储同一种数据类型
——集合:可以存储多种数据类型
Collection集合
——接口,是单列集合的父类
方法:
——add();
Collection collection = new Arraylist();
collection.add(“aaa”);//往集合中添加元素
boolean b = collection.add(“BBB”);//返回值意思是添加是否成功
——addAll();
Collection c1= new ArrayList();
c1.add(100);//这里面100是引用类型,会自动装箱
tips:100----》Integer.valueOf(100)
collection.addAll( c1 );//归并两个集合的元素
——remove();
c1.remove(100);
**——clear();**清空集合中的元素
c1.clear();
tips:Alt+鼠标:选一列
**——removeAll();**删除两个集合的交集
boolean b = c1.removeAll(c2);//若无交集,返回false
A集合removeAll(B集合):
A集合会移除两个交集元素,若移除了返回true,没有就为false
与判断相关的方法
c1.contains(100);//判断集合中是否有这个元素
c1.containsAll©;//判断c中的集合元素都能在c1中找到
判断一个集合是否为空
c1.isEmpty();
获取集合的长度
c1.size();//若长度为0,也是空
遍历集合
遍历Collection需要获取一个迭代器
接口Iterator
Iterator iterator = collection.iterator();
whlie(iterator.hasnext()){
Object obj = iterator.next();//移那个指针(可手动)
System.out.println(obj);
}
取两个集合的交集元素
boolean b = c1.retainAll©;//返回值是表明c1集合有没有发生改变,发生变化返回true,则false
把一个集合转换成数组
Object[] obj = c1.toArray();
//遍历中可以对元素进行向下转型
for(int i=0;i<obj.length;i++){
Integer obj = (Integer) obj[i];
System.out.println(obj.intValue());
}
#### List接口中特有的方法
List list = new ArrayList();
——在指定索引处添加元素
list.add(0,2000);//加在索引为0的位置处
——根据索引获取元素
Object o = list.get(list.size() - 1);
System.out.println(o);
——根据起始索引,终止索引,截取一段新元素放入
List list1 = list.subList(2, 4);
System.out.println(list1);
——根据索引修改元素
list.set(list.size()-1,5000);
——删除
list.remove(2);
list.remove(Integer.valueOf(2000));//假如是Integer类型,删除时,区分不出索引与对象,若要根据元素删,就把元素包装一下
遍历方式
采用for循环遍历:
for(int i= 0;i<list.size();i++){
Object o = list.get(i);
System.out.println(o);
}
ListIterator listIterator = list.listIterator();
正向迭代:listIterator.hasnext();
反向迭代:listIterator.previous();
在没有正向迭代之前,反向迭代没有作用。
迭代器使用时注意
ConcurrentModificationException 并发修改异常
当你使用迭代器,对集合中的元素,进行迭代,在迭代途中,先要增删集合中的元素,就会出现并发修改异常
原因:通过集合获取到这个迭代器之后,迭代器已经预先知道这个集合中元素个数,会按照既定的元素个数进行迭代,在迭代途中,突然增删元素会打乱迭代顺序,所以会抛出并发生异常
解决:
1、使用迭代器自带迭代增删元素的方法(eg:listIterator.add())
2、用for循环
子类
数据结构:一种存储数据的方式
常见的数据结构:数组、栈、链表、队列、哈希、二叉树
数组:有索引,查询快,增删慢
栈:先进后出,
链表:节点—数值域和地址域,查询慢增删快
队列:先进先出
List——ArrayList、LinkedList、Vector
ArrayList:集合,底层数据结构使用是数组,线程不安全,效率高
Vector:底层数据结构是数组,线程安全效率低
LinkedList:底层数据结构是链表,线程不安全效率高
选择是需求安全?效率?增删多?查询多?
ArrayList方法
ArrayList list = new ArrayList();
list.add(100);
list.add(200);
list.add(300);
list.add(400);
list.add(500);
//根据元素查找元素第一次出现的索引
int index = list.indexOf(100);//找索引
int i = list.lastIndexOf(100);//从最后
list.forEach(new Consumer{
public void accept(Object o){
System.out.println(o)
}
});//Consumer为接口
简化上述代码:
list.forEach((obj)->System.out.println(obj));
Vector
public static void main(String[] args) {
// Vector 底层数据结构是数组,查询快,增删慢,线程安全效率低
/* public void addElement (E obj)
public E elementAt ( int index)
public Enumeration elements ()*/
Vector vector = new Vector();
vector.add(200);
vector.addElement(300);
vector.add(200);
vector.addElement(300);
vector.add(200);
vector.addElement(300);
/* Object o = vector.get(0);
Object o1 = vector.elementAt(1);
lastElement()
返回向量的最后一个组件。
firstElement()
返回第一个组件(在指数 0项目)这个载体。
removeElement(Object obj)
从该向量中移除第一个(最低索引)发生的参数。
void removeElementAt(int index)
在指定的索引中删除组件。
setElementAt(E obj, int index)
设置组件在指定的 index这个向量是指定的对象。
*/
Enumeration elements = vector.elements();
while (elements.hasMoreElements()){
Object o = elements.nextElement();
ystem.out.println(o);
}
LinkedList
public static void main(String[] args) {
//LinkedList 底层数据结构是链表,增删快查询慢,线程不安全效率高
/*
* void addFirst(E e)
在此列表的开始处插入指定的元素。
void addLast(E e)
将指定的元素列表的结束。
*
* public void addFirst(E e)及addLast(E e)
public E getFirst()及getLast()
public E removeFirst()及public E removeLast()
*
* */
LinkedList linkedList = new LinkedList();
linkedList.addLast("eeee");
linkedList.add("aaa");
linkedList.addFirst("bbb");
linkedList.add("ccc");
System.out.println(linkedList);
Object o = linkedList.get(0);
Object first = linkedList.getFirst();
Object first2 = linkedList.getFirst();
System.out.println(first2);
System.out.println(first);
System.out.println(linkedList);
例子
需求:请用LinkedList模拟栈数据结构的集合,并测试
public class MyTest {
public static void main(String[] args) {
MyList myList = new MyList();
myList.addObj(100);
myList.addObj(200);
myList.addObj(300);
myList.addObj(400);
myList.addObj(500);
Object obj=myList.get();
System.out.println(obj);
obj = myList.get();
System.out.println(obj);
obj = myList.get();
System.out.println(obj);
obj = myList.get();
System.out.println(obj);
obj = myList.get();
System.out.println(obj);
System.out.println("==============");
obj = myList.get();
System.out.println(obj);
}
}
public class MyList {
LinkedList linkedList;
public MyList() {
linkedList= new LinkedList();
}
public void addObj(Object obj) {
linkedList.addFirst(obj);
}
public Object get() {
Object obj= linkedList.pop();
linkedList.addLast(obj);
return obj;
}
}
集合是存储多种引用数据类型
若使用泛型,就可明确集合中到底放什么样的数据类型
泛型机制:是一种将数据类型明确工作,推迟到创建对象,或调用方法时,再去明确的一种机制;
语法:可以使用在 类 接口 方法 <引用类型,引用类型,。。。。>
集合明确了泛型的具体类型,那么这个集合只能存储这种类型;
好处在于:将问题提前到了编译器,避免了向下转型
tips:只在编译期有效,在运行期就擦除了
泛型使用在接口上
interface MyInterface<T,R>{ //在接口上使用泛型
R set(T t);
}
**什么时候明确泛型:**1、子类在实现接口时,可以明确接口上的泛型到底是什么类型
public static void main(String[] args) {
//泛型接口 什么时候去明确
//匿名内部类
new MyInterface<Integer,Integer>(){
@Override
public Integer set(Integer integer) {
return null;
}
};
}
}
//子类在实现接口时,可以以明确接口上的泛型到底是什么类型
class Son implements MyInterface<String,Integer>{
@Override
public Integer set(String s) {
return null;
}
}
2、匿名内部类:
new Myinterface<Integer,Integer>{
}
泛型使用在方法上
public class MyTest {
public static void main(String[] args) {
//方法上的泛型,在你调用方法时,再去明确
AA aa = new AA();
aa.set(3.14);
aa.set(200);
aa.set("abc");
}
}
class AA{
/* public void set(Object str) {
System.out.println(str);
}*/
//泛型方法
public<P> void set(P str) {
System.out.println(str);
}
/*
泛型统配符
——<?>
——<? super Animal>//向上限定
——<? extends Animal>//向下限定
public class MyTest2 {
public static void main(String[] args) {
ArrayList<Dog> objects = new ArrayList<Dog>();
//?泛型统配符
ArrayList<?> objects2 = new ArrayList<Cat>();
//向上限定
ArrayList<? super Animal> objects3 = new ArrayList<Animal>();
//ArrayList<? super Animal> objects4 = new ArrayList<Dog>();
ArrayList<? super Animal> objects4 = new ArrayList<Object>();
//向下限定
ArrayList<? extends Animal> objects5 = new ArrayList<Dog>();
ArrayList<? extends Animal> objects6= new ArrayList<Cat>();
ArrayList<? extends Animal> objects7 = new ArrayList<Animal>();
ArrayList<Number> list = new ArrayList<>();
list.add(20);
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(200);
list.addAll(list2);
}
}
class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}
增强for循环
for(遍历容器中元素的类型 当前元素变量名:容器名){
System.out.println(当前元素变量名);
}
增强for循环遍历集合
需求用索引作判断,使用普通for
需求只是遍历元素,使用增强for
tips:增强for循环底层用的是迭代器在迭代,在使用遍历元素中不能增删元素,会报并发修改异常;
例子:
遍历一个student对象
可变参数
一次可接收多个参数;本质是个数组
格式:数据类型 … 参数名
public class MyTest {
public static void main(String[] args) {
int sum = add(1, 2);
int sum2 = add(1, 2, 3);
int sum3 = add(1, 2, 3, 4);
//可变参数:一次可以接收多个参数
System.out.println(sum);
System.out.println(sum2);
System.out.println(sum3);
}
//可变参数 数据类型 ... 参数名
//可变参数 本质是个数组
//如果说一个方法上,有普通参数,也有可变参数,可变参数肯定是最后一个参数
private static int add(int b,int... num) {
//System.out.println(num.length);
int sum=0;
for (int i : num) {
sum+=i;
}
return sum+b;
}
tips:如果说一个方法上,有普通参数,也有可变参数,可变参数放是最后一个参数
Arrays 数组工具类
List
把集合转换成数组:Object[] obj= new ArrayList< Integer>.toArray();
数组转换成集合:——asList()方法
Integer[] integers={20,30,40,50,60};
List< Integer> integers1 = Arrays.asList(integers);
public class MyTest {
public static void main(String[] args) {
//Arrays 数组工具类
//List
//把集合转换成数组
// Object[] objects = new ArrayList<Integer>().toArray();
//把一个数组转换成集合
// static <T> List < T > asList(T...a)
// 返回一个受指定数组支持的固定大小的列表。
Integer[] integers = {20, 30, 50, 60};
//如果你给该方法,传入的是一个引用类型数组,那么他会取出数组中的元素,放到集合中
List<Integer> integers1 = Arrays.asList(integers);
for (Integer integer : integers1) {
System.out.println(integer);
}
System.out.println("=====================================");
Integer[] integers2 = {20, 30, 50, 60};
Integer[] integers3 = {20, 30, 50, 60};
//假如你传入两个以上的数组,他是把数组对象作为元素,放到集合中
List<Integer[]> integers4 = Arrays.asList(integers, integers2);
System.out.println(integers4);
Integer integer = integers4.get(0)[0];//取第一个数组对象再取集合中的第一个元素,打印20
System.out.println(integer);
System.out.println("================");
Integer[] integers5 = {20, 30, 50, 60};
List<Integer> integers6 = Arrays.asList(integers5);
int[] ints = {20, 30, 50, 60};
//当你传入一个基本类型数组,那么转换成集合,集合放到是数组对象
List<int[]> ints1 = Arrays.asList(ints);
int[] ints2 = ints1.get(0);//取到数组对象ints={20, 30, 50, 60}
int[] ints3 = {20, 30, 50, 60};
int[] ints4 = {20, 30, 50, 60};
List<int[]> ints8 = Arrays.asList(ints3, ints4);
List<Integer> integers7 = Arrays.asList(20, 30, 50, 30, 80);
//通过asList(20,30,50,30,80);这个方法转换过来的集合,只能对集合中的元素查询和修改,长度不可变!增删会出错
}
}
若给该方法传入一个引用类型数组,那么会取出该数组中的元素放到集合中,假如传入两个以上数组,会把数组对象作为元素放入集合中!
集合嵌套集合
补充:
市场调研
需求文档——项目经理
UI设计师——出效果图
DBA——设计数据库
后台开发——接口文档,数据JSON
开发环境:win7 JDK1.8 MySQL5.5 IDEA2018.。。。
分模块开发
遵循MVC 设计规范
JavaWEB作为对这个规范的实现,有一个经典的三层架构
M:mode
V:View
C:controller