Java开发过程中,集合使用的一些问题记录

问题记录

集合是每个开发者一定要使用的工具类,以下记录几点常遇到的问题

1.Arrays.asList

Arrays.asList(E)得到的List是一个内部类java.util.Arrays.ArrayList


没有定义add和remove方法,而且定义的同时List的实际引用就是数组本身。

所以修改转换后的List和数组效果都是双向的。

由基本类型数组转换来的List存放的是数组的引用,list只有一个元素


由于没有定义add和remove等,强行调用会报错,究其原因就是因为List保存的是数组的引用,数组定义后便固定长度,对数组进行长度操作都会报错

2.不可变List

通过static final 定义的常量仍然可以被修改

暴露出去的常量使用Collections.unmodifiableList(E)控制,当被尝试修改时会抛出java.lang.UnsupportedOperationException

3.初始化问题

List定义时初始化



千万不能使用list.add(),因为list还没有初始化出来
map同理可以直接put

4.forEach

Stream中的forEach是对迭代器简单的封装,接受一个Consumer对象
其中Consumer还能返回一个Consumer对象以达到串行化。

  public static void main(String[] args) {
    ConsumerTest02 test = new ConsumerTest02();
    List<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8, 9);
    test.print(list, item -> System.out.print(" consumer1:" + item * 2), item -> System.out.print(" consumer2:" + item * 3));
}

    /*
      andThen方法, 将参数传递给调用者执行accept方法,然后再传给第二个consumer执行accept方法。
    */
  public void print(List<Integer> list, IntConsumer con1, IntConsumer con2) {
    list.forEach(item -> con1.andThen(con2).accept(item));
}

这样就可以在一次循环中处理多个业务内容
这个时候就有人问了,那我都写在一个Consumer不行吗干嘛要分开多麻烦
这种处理方式就像是流水线,前面的人加工完到后面的人加工下一步,一步到胃当然可以,但是流程就缺乏管理,有问题不容易查找。
分开之后流程清晰,看每一步处理的结果就能判断问题所在。
当然如果也不并不复杂不需要这样分开,反而适得其反。

另一方面,forEach不能被打断,如果有需要打断的场景,还是用回for循环

5.equals和hashcode

重写equals()方法就必须重写hashCode()方法主要是针对HashSet和Map集合类型,而对于List集合倒没什么影响。

原因: 在向HashSet集合中存入一个元素时,HashSet会调用该对象(存入对象)的hashCode()方法来得到该对象的hashCode()值,然后根据该hashCode值决定该对象在HashSet中存储的位置。简单的说:HashSet集合判断两个元素相等的标准是:两个对象通过equals()方法比较相等,并且两个对象的HashCode()方法返回值也相等。如果两个元素通过equals()方法比较返回true,但是它们的hashCode()方法返回值不同,HashSet会把它们存储在不同的位置,依然可以添加成功。

这就是问题所在:就是如果你只重写equals()方法,而不重写hashCode(),如果equals()为true,而它们的hashCode()方法返回值肯定不一样,因为它们都不是同一对象所以内存地址肯定不一样,所以它还是添加成功了,那么其实你写的equals()方法根本没用。

6.Stream中groupBy

对集合进行分组这是常用的操作
如果想要进行对多字段进行分组,可以通过字符串拼接的方式
list.stream().collect(Collectors.groupingBy(user -> user.getName() + "_" + user.getId()));
注意为空的处理
同时,如果想保持分组后的map有序,可以使用Treemap或者LinkedHashMap
一个是优先排序,一个是按插入顺序排序
LinkedHashMap<String, List<Score>> scores = list.stream().collect(Collectors.groupingBy(Score::getName, LinkedHashMap::new, Collectors.toList()));// 按照姓名分组
多级分组: 嵌套使用groupingBy即可

List<String> views = Lists.newArrayList("wsbsq","hello word","b8fw", "word", "wall", "ad");  
Map<Object, Map<Object, List<String>>> res = views.stream().collect(groupingBy(str ->str.charAt(0),groupingBy(String::length)));  
// {a={2=[ad]}, b={4=[b8fw]}, w={4=[word, wall], 5=[wsbsq]}, h={10=[hello word]}}  
7.stream中的reduce

reduce一般是接受一个BinaryOperator类型的lambada表达式,因为计算结果可能为空所以返回一个Optional

List<Integer> numList = Arrays.asList(1,2,3,4,5);  
int result = numList.stream().reduce((a,b) -> a + b ).get();  

或者可以在reduce时给定一个初始值
int result = numList.stream().reduce(0,(a,b) -> a + b );
这样即使list中无法计算出来,也会至少有0
reduce每次都会返回当前节点和上一次处理的结果,所以还能做到像这样的操作

List<Integer> numList = Arrays.asList(1, 2, 3, 4, 5, 6);
ArrayList<String> result = numList.stream().reduce(new ArrayList<String>(), (a, b) -> {
    a.add("element-" + Integer.toString(b));
    return a;
}, (a, b) -> null);
System.out.println(result);
//[element-1, element-2, element-3, element-4, element-5, element-6]

按照自己的逻辑处理每一个数据,可以改变数据结构就连size都可以不一样

未完待续

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350