问题:我之前以为:
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,提供了long
i += 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;
首先项目名字那按右键选Add Framework Support
或者选添加框架支持
,然后选Maven
,在pom.xml
里写入下面这个
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
</dependencies>
最靠谱的方法,用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));
}
}
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);
}
}
但这样做会有坑:
add()
方法或者remove()
方法,都会抛异常UnsupportedOperationException。数组
的值,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);// 这里
}
}
在Java中有多种遍历HashMap的方法。
让我们回顾一下最常见的方法和它们各自的优缺点。
由于所有的Map都实现了Map接口,所以接下来方法适用于所有Map(如:HaspMap,TreeMap,LinkedMap,HashTable,ConcurrentHashMAp,……)
这是最常见的方法,并在大多数情况下更可取的。当你在循环中需要使用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异常。
如果你只需要用到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%)并且代码更简洁
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迭代(方法二)
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(低效的)
方法。
如下表所示,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—基础语法系列(三)
未完待续
如有错误,还请多多指教!
转载或者引用本文内容请注明来源及原作者:橘足轻重;