> 文章列表 > Java编程问题top100---基础语法系列(一)

Java编程问题top100---基础语法系列(一)

Java编程问题top100---基础语法系列(一)

Java编程问题top100---基础语法系列一

  • 一、Java += 操作符实质
  • 二、将InputStream转换为String
      • 使用IOUtils
      • 自己写轮子
  • 三、将数组转换为List
  • 四、如何遍历map对象
      • 使用For-Each迭代entries(方法一)
      • 使用For-Each迭代keys和values(方法二)
      • 使用Iterator迭代(方法三)
        • 使用泛型
        • 不使用泛型
      • 迭代keys并搜索values(低效的)(方法四)
      • 总结
  • 五、public,protected,private,不加修饰符。有什么区别呢?
  • Java编程问题top100---基础语法系列导航

记得这个是当时刚入学那会尝试去看的一个github上的优秀内容,当时很多东西看得云里雾里,不太懂。

现在正好有空了,再来一次,会稍作修改再加上代码实践,有问题可以留言。

重温的同时,希望对你能有所帮助。

以下系列将会是对stackoverflow上Java相关、投票数TOP100的问答(精修版)。

一、Java += 操作符实质

问题:我之前以为:
i += j 等同于 i = i + j;
但假设有:
int i = 5; long j = 8;
这时 i = i + j 不能编译,但 i += j 却可以编译。这说明两者还是有差别的
这是否意味着,i += j,实际是等同于 i= (type of i) (i + j)呢?

// Java += 操作符实质
public class test01 {public static void main(String[] args) {int i = 5;long j = 8;// i = i + j;// 编译报错,需要的类型int,提供了longi += j; // 这行没有问题i = i + (int) j; // 这行也没问题}
}

回答
复合赋值表达式E1 op= E2来说, (诸如 i += j i -= j i*=j i/=j等等),其实是等同于 E1 = (T)((E1) op (E2))
其中,E1和E2表示两个操作数,T是E1这个元素的类型
举例来说,如下的代码
int i = 5;long j = 8;
i += j;等同于i = (int)(i + j); 也就是(i + j)先执行,然后(i + j)的结果强制类型转换为int类型
新人注意:表达式i = (int)(i + j); (i + j)这个是带括号的。
它也等价于i = i + (int) j;

二、将InputStream转换为String

首先项目名字那按右键选Add Framework Support或者选添加框架支持,然后选Maven,在pom.xml里写入下面这个

    <dependencies><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version></dependency></dependencies>

使用IOUtils

最靠谱的方法,用Apache commons IOUtils
文档test02.txt

ABC a b ABc b
你好
//将InputStream转换为String
public class test02 {public static void main(String[] args) throws Exception {FileInputStream inputStream = new FileInputStream("D:\\test02.txt");String encoding = "UTF-8";StringWriter writer = new StringWriter();IOUtils.copy(inputStream, writer, encoding);String theString = writer.toString();// String theString = IOUtils.toString(inputStream, encoding);// 这个方法其实封装了上面的方法,减少了一个参数}
}

或者

String theString = IOUtils.toString(inputStream, encoding);
//这个方法其实封装了上面的方法,减少了一个参数 

自己写轮子

如果不想引入Apache库,也可以这样做

//将InputStream转换为String
public class test02 {static String convertStreamToString(InputStream is) {Scanner s = new Scanner(is).useDelimiter("你好");//读取到你好这个词就会停止输入return s.hasNext() ? s.next() : "";}public static void main(String[] args) throws FileNotFoundException {FileInputStream fileInputStream = new FileInputStream("test.txt");System.out.println(convertStreamToString(fileInputStream));}
}

三、将数组转换为List

1、最简单的for循环遍历挨个赋值给List。
2、Arrays.asList(array);

// 将数组转换为List
public class test03 {public static void main(String[] args) {Integer[] array = {1, 2, 3, 4};List<Integer> arrayLists = Arrays.asList(array);// 这里System.out.println(arrayLists);}
}

但这样做会有坑:

  1. 生成的list,是固定长度的。也就是说,如果调用它的add()方法或者remove()方法,都会抛异常UnsupportedOperationException。
  2. 如果修改数组的值list中的对应值也会改变

因为Arrays.asList() 返回的是Arrays里的内部静态类,而不是Java.util.ArrayList这个类。
这个java.util.Arrays.ArrayList有set(),get(),contains()方法,但是没有任何add() 方法,所以它是固定大小的.

建议用这个
Collections.addAll(arrayLists, array);

// 将数组转换为List
public class test03 {public static void main(String[] args) {Integer[] array = {1, 2, 3, 4};List<Integer> arrayLists = new ArrayList<>();Collections.addAll(arrayLists, array);// 这里}
}

四、如何遍历map对象

在Java中有多种遍历HashMap的方法。
让我们回顾一下最常见的方法和它们各自的优缺点。
由于所有的Map都实现了Map接口,所以接下来方法适用于所有Map(如:HaspMap,TreeMap,LinkedMap,HashTable,ConcurrentHashMAp,……)

使用For-Each迭代entries(方法一)

这是最常见的方法,并在大多数情况下更可取的。当你在循环中需要使用Map的键和值时,就可以使用这个方法

public class test04 {public static void main(String[] args) {Map<String, Integer> map = new HashMap<>();// map = null;map.put("a", 1);testOne(map);}public static void testOne(Map<String, Integer> map) {if (map != null && !map.isEmpty()) {for (Map.Entry<String, Integer> entry : map.entrySet()) {System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());}}else {System.out.println(map);}}
}

注意:遍历之前你应该判断是否为空引用。如果遍历的map是null的话,For-Each循环会抛出NullPointerException异常。

使用For-Each迭代keys和values(方法二)

如果你只需要用到map的keys或values时,你可以遍历KeySet或者values代替entrySet

    public static void testTwo(Map<String, Integer> map) {if (map != null && !map.isEmpty()) {for (String key : map.keySet()) {System.out.println("Key = " + key);}for (Integer value : map.values()) {System.out.println("Value = " + value);}}}

这个方法比entrySet迭代具有轻微的性能优势(大约快10%)并且代码更简洁

使用Iterator迭代(方法三)

使用泛型

    public static void testThree(Map<String, Integer> map) {Iterator<Map.Entry<String, Integer>> entries = map.entrySet().iterator();while (entries.hasNext()) {Map.Entry<String, Integer> entry = entries.next();System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());}}

不使用泛型

public static void testFour(Map<String, Integer> map) {if (map != null && !map.isEmpty()) {Iterator entries = map.entrySet().iterator();while (entries.hasNext()) {Map.Entry entry = (Map.Entry) entries.next();String key = (String) entry.getKey();Integer value = (Integer) entry.getValue();System.out.println("Key = " + key + ", Value = " + value);}} else {System.out.println(map);}}

你可以使用同样的技术迭代keyset或者values
首先,它是遍历java 5 以前版本的map的唯一方法。
第二是可以让你在迭代的时候从map中删除entries的(通过调用iterator.remover())唯一方法。
如果你试图在For-Each迭代的时候删除entries,你将会得到unpredictable resultes 异常。
从性能方面看,这个方法等价于使用For-Each迭代(方法二)

迭代keys并搜索values(低效的)(方法四)

    public static void testFive(Map<String, Integer> map) {if (map != null && !map.isEmpty()) {for (String key : map.keySet()) {Integer value = map.get(key);System.out.println("Key = " + key + ", Value = " + value);}} else {System.out.println(map);}}

比方法一更简洁,但是实际更慢更低效,通过key得到value值更耗时

总结

如果你只需要使用key或者value使用方法二使用For-Each迭代keys和values,如果你使用java 5 以前的版本或者打算在迭代的时候移除entries,使用方法三使用Iterator迭代其他情况请使用方法一For-Each迭代entries方法。避免使用迭代keys并搜索values(低效的)方法。

五、public,protected,private,不加修饰符。有什么区别呢?

如下表所示,Y表示能访问(可见性),N表示不能访问,例如第一行的第3个Y,表示类的变量/方法如果是用public修饰,它的子类能访问这个变量/方法

修饰符 类内部 同个包(package) 子类 其他范围
public Y Y Y Y
protected Y Y Y N
无修饰符 Y Y N or Y(见说明) N
private Y N N N

说明:
需要特别说明“无修饰符”这个情况,子类能否访问父类中无修饰符的变量/方法,取决于子类是否在同一个包中。如果子类和父类在同一个包中,那么子类可以访问父类中的无修饰符的变量/方法,否则不行。

Java编程问题top100—基础语法系列导航

Java编程问题top100—基础语法系列(一)
Java编程问题top100—基础语法系列(二) 待更新
Java编程问题top100—基础语法系列(三) 待更新

如有错误,还请多多指教!
转载或者引用本文内容请注明来源及原作者:橘足轻重;