java一些精干知识点分享
- 2. java小干货
- 2.1循环遍历
- 2.2可变参数
- 2.3 list和数组转化
- 2.3.1 数组转list
- 2.3.2 list转数组
- 2.4 值传递和地址传递
- 2.4.1值传递
- 2.4.2 地址传递
- 2.4.3易错点总结
- 2.5 数组
- 数组帮助类Arrays
- 2.5 基本数据类型和包装类
- 2.5集合
- 2.6文件流
- 2.7java代码块、内部类和匿名类
- 2.8 java泛型及通配符
- 2.9 日期类LocalDate
- 2.10枚举
- 2.11 java常见数据结构
2. java小干货
2.1循环遍历
数组、list、map都需要遍历循环,有下面集中循环方式
1.for ecah
list可以是一个数组、list、set
// list可以是一个数组、list、set
for(bject o :list)
{
}
2.Iterator迭代器
list可以是list、set类的子类
Iterator iter = list.iterator();
while(iter.hasNext()){
Object o = iter.next();
}
3.loop with size
可以是数组、list能得到索引长度的类及子类
for(int i=0;i<list.size();i++){
Object o= list.get(i);
}
4.lambda表达式
list.forEach(
(value)->{
System.out.println(value);
}
);
代码示例
public class GanHuo {
@Test
public void t1(){
//1.for-each遍历,最简单,但无法获得索引
System.out.println("=======for(Object:list)循环=========");
String arrayStr[]=new String[]{"1","2","3"};
//1-1 数组
System.out.println("for-each遍历数组-----------");
for (String s : arrayStr) {
System.out.println("arrayStr:"+s);
}
//1-2 list
List<Integer> list= Arrays.asList(1,2,3,4);
System.out.println("for-each遍历list-----------");
for (Integer i : list) {
System.out.println("list:"+i);
}
//1-3 遍历map
Map<String,String> map=new HashMap<>();
System.out.println("for-each遍历Map-----------");
map.put("1", "111");
map.put("2", "222");
map.put("3", "222");
//得到key的collecton
Set<String> keySet=map.keySet();
for(String key:keySet){
System.out.println("map["+key+"]="+map.get(key));
}
}
@Test
public void t2(){
System.out.println("=======Iterator循环================");
//1-2 list
List<Integer> list= Arrays.asList(1,2,3,4);
System.out.println("Iterator 遍历list-----------");
Iterator iter=list.iterator();
while (iter.hasNext()) {
System.out.println("list:"+iter.next());
}
//1-3 遍历map
Map<String,String> map=new HashMap<>();
System.out.println("Iterator 遍历Map-----------");
map.put("1", "111");
map.put("2", "222");
map.put("3", "222");
//得到key的collecton
Set<String> keySet=map.keySet();
iter=keySet.iterator();
while (iter.hasNext()) {
String key= (String) iter.next();
System.out.println("map["+key+"]="+map.get(key));
}
}
@Test
public void t3(){
System.out.println("=======for。size循环================");
//1-1 数组
String arrayStr[]=new String[]{"1","2","3"};
System.out.println("loop size 遍历数组-----------");
for (int i = 0; i < arrayStr.length; i++) {
System.out.println("arrayStr["+i+"]="+arrayStr[i]);
}
//1-2 list
List<Integer> list= Arrays.asList(1,2,3,4);
System.out.println("loop size 遍历list-----------");
for (int i = 0; i < list.size(); i++) {
System.out.println("list["+i+"]="+list.get(i));
}
}
@Test
public void t4(){
System.out.println("=======lambda表达式================");
//list的lambda表达式
List<Integer> list= Arrays.asList(1,2,3,4);
System.out.println("lambda表达式 遍历list-----------");
list.forEach(
(value)->{
System.out.println(value);
}
);
//Map的lambda表达式
Map<String,String> map=new HashMap<>();
System.out.println("lambda表达式 遍历Map-----------");
map.put("1", "111");
map.put("2", "222");
map.put("3", "222");
map.forEach((key, value)->{
System.out.print("key = " + key);
System.out.println(", value = " + value);
});
}
}
2.2可变参数
可变参数是指不指定参数的个数
定义:
数据类型… 变量名
可变参数规范
1.可变参数本身是一个数组
2.可变参数也可传递一个数组
3.可变参数个数不受限制,可无限制,也可没有
4.如果可变参数和常规参数混合,则可变参数要放到最后
5.每个方法最多只能有一个可变参数
代码示例
public class ChangeParam {
public void param(Integer... val){
System.out.println("val包含:"+val.length+"个参数");
for (Integer i : val) {
System.out.println(i);
}
}
/***
如果一个方法里包含常规参数和可变参数,则可变参数必须放置到最后一个
*/
public void param1(String name,Integer age,String... likes){
System.out.println("name:"+name);
System.out.println("age:"+age);
System.out.println("likes-----");
String temp="";
for (String like : likes) {
temp+=like+",";
}
System.out.println(temp);
}
@Test
public void t1(){
//可以传递不受限制的个数
param(1,2,3);
//可以不传参数
param();
//也可传递数组
Integer[] array={1,2,3};
param(array);
//常规和可变参数混合
param1("蒋增奎",20,"火锅","串串","烤鸭");
}
}
2.3 list和数组转化
2.3.1 数组转list
1.使用List=Arrays.asList(数组对象),最简单,但不能新增删除
2.List=new ArrayList<>(Arrays.asList(intArray)),可新增删除,但性能差
3. Collections.addAll(list对象, 数组对象);可新增删除,性能好
4.list= Stream.of(数组对象).collect(Collectors.toList());
@Test
public void array2List(){
System.out.println("=========Arrays.asList=======");
//1---直接用Arrays.asList后不能再新增
System.out.println("1---直接用Arrays.asList后不能再新增");
//基本类型数组
Integer[] intArray={1,2,3};
List<Object> list1= Arrays.asList(intArray);
// list1.add(4); //不能再新增,否则要报异常
printList(list1);
//自定义数组
TestVO[] objArray={new TestVO(1,"jzk"),new TestVO(2,"张三")};
list1=Arrays.asList(objArray);
printList(list1);
//2--Arrays.asList作为构造参数传入,可新增,但性能差
System.out.println("2--Arrays.asList作为构造参数传入,可新增,但性能差");
list1=new ArrayList<>(Arrays.asList(intArray));
list1.add(4);
printList(list1);
//3--Collections.addAll(list,数组);能新增删除,性能好
System.out.println("3--Collections.addAll(list,数组);能新增删除,性能好");
list1=new ArrayList<>();
Collections.addAll(list1, intArray);
list1.add(4);
printList(list1);
//4--使用 Stream;能新增删除,性能好
System.out.println("4--使用 Stream;能新增删除,性能好");
list1= Stream.of(intArray).collect(Collectors.toList());
list1.add(4);
printList(list1);
}
private void printList(List<Object> list){
for (Object o : list) {
System.out.println(o);
}
}
2.3.2 list转数组
核心用到list.toArray()方法
1.Object[] arrays=list.toArray(); 只能获得Object数组
2.对象数组=list.toArray(new 对象[list.size] ) ;//可以获得对应的对象数组
测试代码
@Test
public void list2array(){
List<TestVO> list=getTestVO();
System.out.println("方法1:list.toArray()===========");
//注意:只能用转换成Object[]数组,不能强制转化
Object[] arrays=list.toArray();
for (Object array : arrays) {
System.out.println((TestVO)array);
}
System.out.println("方法2:list.toArray(数组对象)===========");
//这样可获得实际的类
TestVO[] vos=new TestVO[list.size()];
list.toArray(vos );
for (TestVO vo : vos) {
System.out.println(vo);
}
//或者这样写
System.out.println("方法3:list.toArray(数组对象)简写===========");
vos=list.toArray(new TestVO[list.size()]);
for (TestVO vo : vos) {
System.out.println(vo);
}
System.out.println("方法4:String[] strings = list.stream().toArray(String[]::new);===");
TestVO[] vos2=list.stream().toArray( TestVO[]::new);
for (TestVO vo : vos2) {
System.out.println(vo);
}
}
private void printList(List<Object> list){
for (Object o : list) {
System.out.println(o);
}
}
private List<TestVO> getTestVO(){
List<TestVO> list=new ArrayList<>();
list.add(new TestVO(1,"jzk"));
list.add(new TestVO(2,"张三"));
return list;
}
2.4 值传递和地址传递
在学习 Java 编程语言的过程中,我们经常会听到“值传递”和“地址传递”这两个概念。它们是用来描述参数传递方式的术语,而理解它们的区别对于编写高效的代码非常重要。在本文中,我们将详细介绍这两种传递方式,并通过代码示例来说明它们的差异。
2.4.1值传递
在 Java 中,基本数据类型(如整数、布尔值等)都是以值传递的方式进行参数传递。这意味着当我们将一个基本数据类型作为参数传递给一个方法时,方法内部会创建一个新的变量来存储这个参数的值,而不会影响原始的变量。
执行过程
- 首先,在调用方法时,将实际参数的值复制一份,并将这份副本传递给方法进行操作。
- 在方法内部,这个副本的值被赋给一个新的局部变量。
- 在方法执行过程中,对该局部变量的任何改动都不会影响原始的变量,因为它们指向的是不同的内存空间。
- 当方法执行完毕后,这个局部变量和方法的栈帧都会被销毁,而原始的变量的值保持不变。
基本数据类型的传递过程中,传入的值被复制到方法内部,并在方法内部进行操作,但不会影响原始变量的值。
@Test
public void valPass(){
String str="a";
double db= Double.parseDouble("34.5");
Double db1=45.2;
Integer zs=Integer.valueOf(100);
int zs1=200;
boolean b=false;
Boolean b1= true;
System.out.println("str="+str);
System.out.println("db="+db);
System.out.println("db1="+db1);
System.out.println("zs="+zs);
System.out.println("zs1="+zs1);
System.out.println("b="+b);
System.out.println("b1="+b1);
change1(str,db,db1,zs,zs1);
System.out.println("str="+str);
System.out.println("db="+db);
System.out.println("db1="+db1);
System.out.println("zs="+zs);
System.out.println("zs1="+zs1);
}
private void change1(String str,double db,Double db1,int zs,Integer zs1){
System.out.println("============change==========");
str="b";
db=-45.2;
db1=-22.4;
zs=-1;
zs1=-2;
}
执行效果,可以看出这些都是值传递,被引用后并没有改变以前值:
str=a
db=34.5
db1=45.2
zs=100
zs1=200
b=false
b1=true
============change==========
str=a
db=34.5
db1=45.2
zs=100
zs1=200
2.4.2 地址传递
与基本数据类型不同,Java 中的对象类型(如数组、集合、自定义类等)则是以地址传递的方式进行参数传递。这意味着当我们将一个对象作为参数传递给一个方法时,方法内部使用的是这个对象的引用,而不是对象本身。
执行过程
-
创建一个对象并将其引用赋值给一个变量。
-
将这个变量作为参数传递给一个方法。
-
在方法内部,参数变量接收到了对原始对象的引用。
-
在方法内部修改参数变量所指向的对象时,原始对象也会受到影响。
-
方法执行完毕后,返回到原始调用处,可以通过原始变量访问到被修改后的对象。
对象的引用传递意味着传递的是对象的引用,通过引用可以访问和修改原始对象的属性。
测试代码:
@Test
public void addressPass(){
StringBuffer sb=new StringBuffer("aa");
TestVO vo=new TestVO(1,"蒋增奎");
String[] array={"1","2","3"};
List<Integer> list=new ArrayList<>();
list.add(1);list.add(2);
Map<String,Integer> map=new HashMap<>();
map.put("1", 11);
map.put("2", 22);
System.out.println("sb:"+sb);
System.out.println("vo:"+vo);
System.out.println("array:"+ Arrays.toString(array));
System.out.println("list:"+Arrays.toString(list.toArray()));
System.out.println("map:"+map.toString());
System.out.println("================");
change2(sb,vo,array,list,map);
System.out.println("sb:"+sb);
System.out.println("vo:"+vo);
System.out.println("array:"+ Arrays.toString(array));
System.out.println("list:"+Arrays.toString(list.toArray()));
System.out.println("map:"+map.toString());
}
private void change2( StringBuffer sb, TestVO vo,String[] array,
List<Integer> list,Map<String,Integer> map){
sb.append("dd");
vo.setName("蒋大爷");
array[0]="改值11";
list.add(3);
map.put("3",333);
}
效果,地址引用值都会被改变
sb:aa
vo:TestVO(id=1, name=蒋增奎)
array:[1, 2, 3]
list:[1, 2]
map:{1=11, 2=22}
================
sb:aadd
vo:TestVO(id=1, name=蒋大爷)
array:[改值11, 2, 3]
list:[1, 2, 3]
map:{1=11, 2=22, 3=333}
2.4.3易错点总结
易错点
java对象:String ,int等对应的封装类Integer,java.util.Date,BigDecimal是值传递,不是地址传递,虽然他们是对象
值传递VS地址传递