首页 文章 精选 留言 我的

精选列表

搜索[权限提升],共10000篇文章
优秀的个人博客,低调大师

Guava - 拯救垃圾代码,写出优雅高效,效率提升N倍

> 最近在看一个同学代码的时候,发现代码中大量使用了 Google 开源的 Guava 核心库中的内容,让代码简单清晰了不少,故学习分享出 Guava 中我认为最实用的功能。 Guava 项目是 Google 公司开源的 Java 核心库,它主要是包含一些在 Java 开发中经常使用到的功能,如数据校验、不可变集合、计数集合,集合增强操作、I/O、缓存、字符串操作等。并且 Guava 广泛用于 Google 内部的 Java 项目中,也被其他公司广泛使用,甚至在新版 JDK 中直接引入了 Guava 中的优秀类库,所以质量毋庸置疑。 使用方式直接 mavan 依赖引入。 <!-- https://mvnrepository.com/artifact/com.google.guava/guava --> <dependency> <groupid>com.google.guava</groupid> <artifactid>guava</artifactid> <version>30.0-jre</version> </dependency> <!-- more --> 数据校验 数据校验说来十分简单,一是非空判断,二是预期值判断。非空判断我想每一个 Java 开发者都很熟悉,一开始都经常和 NullPointException 打交道。处理的方式我们自然是一个 if( xx == null) 就能轻松解决。预期值判断也是类似,检查数据值是不是自己想要的结果即可。 即使这么简单的操作,我们是不是还经常出错呢?而且写起来的代码总是一行判断一行异常抛出,怎么看都觉得那么优雅。还好,现在就来尝试第一次使用 Guava 吧。 非空判断 String param = "未读代码"; String name = Preconditions.checkNotNull(param); System.out.println(name); // 未读代码 String param2 = null; String name2 = Preconditions.checkNotNull(param2); // NullPointerException System.out.println(name2); 引入了 Guava 后可以直接使用 Preconditions.checkNotNull 进行非空判断,好处为觉得有两个,一是语义清晰代码优雅;二是你也可以自定义报错信息,这样如果参数为空,报错的信息清晰,可以直接定位到具体参数。 String param2 = null; String name2 = Preconditions.checkNotNull(param2,"param2 is null"); // java.lang.NullPointerException: param2 is null 预期值判断 和非空判断类似,可以比较当前值和预期值,如果不相等可以自定义报错信息抛出。 String param = "www.wdbyte.com2"; String wdbyte = "www.wdbyte.com"; Preconditions.checkArgument(wdbyte.equals(param), "[%s] 404 NOT FOUND", param); // java.lang.IllegalArgumentException: [www.wdbyte.com2] 404 NOT FOUND 是否越界 Preconditions 类还可以用来检查数组和集合的元素获取是否越界。 // Guava 中快速创建ArrayList List<string> list = Lists.newArrayList("a", "b", "c", "d"); // 开始校验 int index = Preconditions.checkElementIndex(5, list.size()); // java.lang.IndexOutOfBoundsException: index (5) must be less than size (4) 代码中快速创建 List 的方式也是 Guava 提供的,后面会详细介绍 Guava 中集合创建的超多姿势。 不可变的集合 创建不可变集合是我个人最喜欢 Guava 的一个原因,因为创建一个不能删除、不能修改、不能增加元素的集合实在是太实用了。这样的集合你完全不用担心发生什么问题,总的来说有下面几个优点: 线程安全,因为不能修改任何元素,可以随意多线程使用且没有并发问题。 可以无忧的提供给第三方使用,反正修改不了。 减少内存占用,因为不能改变,所以内部实现可以最大程度节约内存占用。 可以用作常量集合。 创建方式 说了那么多,那么到底怎么使用呢?赶紧撸起代码来。 // 创建方式1:of ImmutableSet<string> immutableSet = ImmutableSet.of("a", "b", "c"); immutableSet.forEach(System.out::println); // a // b // c // 创建方式2:builder ImmutableSet<string> immutableSet2 = ImmutableSet.<string>builder() .add("hello") .add(new String("未读代码")) .build(); immutableSet2.forEach(System.out::println); // hello // 未读代码 // 创建方式3:从其他集合中拷贝创建 ArrayList<string> arrayList = new ArrayList(); arrayList.add("www.wdbyte.com"); arrayList.add("https"); ImmutableSet<string> immutableSet3 = ImmutableSet.copyOf(arrayList); immutableSet3.forEach(System.out::println); // www.wdbyte.com // https 都可以正常打印遍历结果,但是如果进行增删改,会直接报 UnsupportedOperationException . 其实 JDK 中也提供了一个不可变集合,可以像下面这样创建。 ArrayList<string> arrayList = new ArrayList(); arrayList.add("www.wdbyte.com"); arrayList.add("https"); // JDK Collections 创建不可变 List List<string> list = Collections.unmodifiableList(arrayList); list.forEach(System.out::println);// www.wdbyte.com https list.add("未读代码"); // java.lang.UnsupportedOperationException 注意事项 使用 Guava 创建的不可变集合是拒绝 null 值的,因为在 Google 内部调查中,95% 的情况下都不需要放入 null 值。 使用 JDK 提供的不可变集合创建成功后,原集合添加元素会体现在不可变集合中,而 Guava 的不可变集合不会有这个问题。 List<string> arrayList = new ArrayList&lt;&gt;(); arrayList.add("a"); arrayList.add("b"); List<string> jdkList = Collections.unmodifiableList(arrayList); ImmutableList<string> immutableList = ImmutableList.copyOf(arrayList); arrayList.add("ccc"); jdkList.forEach(System.out::println);// result: a b ccc System.out.println("-------"); immutableList.forEach(System.out::println);// result: a b 如果不可变集合的元素是引用对象,那么引用对象的属性是可以更改的。 其他不可变集合 不可变集合除了上面演示的 set 之外,还有很多不可变集合,下面是 Guava 中不可变集合和其他集合的对应关系。 可变集合接口 属于JDK还是Guava 不可变版本 Collection JDK ImmutableCollection List JDK ImmutableList Set JDK ImmutableSet SortedSet/NavigableSet JDK ImmutableSortedSet Map JDK ImmutableMap SortedMap JDK ImmutableSortedMap Multiset Guava ImmutableMultiset SortedMultiset Guava ImmutableSortedMultiset Multimap Guava ImmutableMultimap ListMultimap Guava ImmutableListMultimap SetMultimap Guava ImmutableSetMultimap BiMap Guava ImmutableBiMap ClassToInstanceMap Guava ImmutableClassToInstanceMap Table Guava ImmutableTable 集合操作工厂 其实这里只会介绍一个创建方法,但是为什么还是单独拿出来介绍了呢?看下去你就会大呼好用。虽然 JDK 中已经提供了大量的集合相关的操作方法,用起来也是非常的方便,但是 Guava 还是增加了一些十分好用的方法,保证让你用上一次就爱不释手, 创建集合。 // 创建一个 ArrayList 集合 List<string> list1 = Lists.newArrayList(); // 创建一个 ArrayList 集合,同时塞入3个数据 List<string> list2 = Lists.newArrayList("a", "b", "c"); // 创建一个 ArrayList 集合,容量初始化为10 List<string> list3 = Lists.newArrayListWithCapacity(10); LinkedList<string> linkedList1 = Lists.newLinkedList(); CopyOnWriteArrayList<string> cowArrayList = Lists.newCopyOnWriteArrayList(); HashMap<object, object> hashMap = Maps.newHashMap(); ConcurrentMap<object, object> concurrentMap = Maps.newConcurrentMap(); TreeMap<comparable, object> treeMap = Maps.newTreeMap(); HashSet<object> hashSet = Sets.newHashSet(); HashSet<string> newHashSet = Sets.newHashSet("a", "a", "b", "c"); Guava 为每一个集合都添加了工厂方法创建方式,上面已经展示了部分集合的工厂方法创建方式。是不是十分的好用呢。而且可以在创建时直接扔进去几个元素,这个简直太赞了,再也不用一个个 add 了。 集合交集并集差集 过于简单,直接看代码和输出结果吧。 Set<string> newHashSet1 = Sets.newHashSet("a", "a", "b", "c"); Set<string> newHashSet2 = Sets.newHashSet("b", "b", "c", "d"); // 交集 SetView<string> intersectionSet = Sets.intersection(newHashSet1, newHashSet2); System.out.println(intersectionSet); // [b, c] // 并集 SetView<string> unionSet = Sets.union(newHashSet1, newHashSet2); System.out.println(unionSet); // [a, b, c, d] // newHashSet1 中存在,newHashSet2 中不存在 SetView<string> setView = Sets.difference(newHashSet1, newHashSet2); System.out.println(setView); // [a] 有数量的集合 这个真的太有用了,因为我们经常会需要设计可以计数的集合,或者 value 是 List 的 Map 集合,如果说你不太明白,看下面这段代码,是否某天夜里你也这样写过。 统计相同元素出现的次数(下面的代码我已经尽可能精简写法了)。 JDK 原生写法: // Java 统计相同元素出现的次数。 List<string> words = Lists.newArrayList("a", "b", "c", "d", "a", "c"); Map<string, integer> countMap = new HashMap<string, integer>(); for (String word : words) { Integer count = countMap.get(word); count = (count == null) ? 1 : ++count; countMap.put(word, count); } countMap.forEach((k, v) -&gt; System.out.println(k + ":" + v)); /** * result: * a:2 * b:1 * c:2 * d:1 */ 尽管已经尽量优化代码,代码量还是不少的,那么在 Guava 中有什么不一样呢?在 Guava. 中主要是使用 HashMultiset 类,看下面。 ArrayList<string> arrayList = Lists.newArrayList("a", "b", "c", "d", "a", "c"); HashMultiset<string> multiset = HashMultiset.create(arrayList); multiset.elementSet().forEach(s -&gt; System.out.println(s + ":" + multiset.count(s))); /** * result: * a:2 * b:1 * c:2 * d:1 */ 是的,只要把元素添加进去就行了,不用在乎是否重复,最后都可以使用 count 方法统计重复元素数量。看着舒服,写着优雅,HashMultiset 是 Guava 中实现的 Collection 类,可以轻松统计元素数量。 一对多,value 是 List 的 Map 集合。 假设一个场景,需要把很多动物按照种类进行分类,我相信最后你会写出类似的代码。 JDK 原生写法: HashMap<string, set<string>&gt; animalMap = new HashMap&lt;&gt;(); HashSet<string> dogSet = new HashSet&lt;&gt;(); dogSet.add("旺财"); dogSet.add("大黄"); animalMap.put("狗", dogSet); HashSet<string> catSet = new HashSet&lt;&gt;(); catSet.add("加菲"); catSet.add("汤姆"); animalMap.put("猫", catSet); System.out.println(animalMap.get("猫")); // [加菲, 汤姆] 最后一行查询猫得到了猫类的 "加菲" 和 ”汤姆“。这个代码简直太烦做了,如果使用 Guava 呢? // use guava HashMultimap<string, string> multimap = HashMultimap.create(); multimap.put("狗", "大黄"); multimap.put("狗", "旺财"); multimap.put("猫", "加菲"); multimap.put("猫", "汤姆"); System.out.println(multimap.get("猫")); // [加菲, 汤姆] HashMultimap 可以扔进去重复的 key 值,最后获取时可以得到所有的 value 值,可以看到输出结果和 JDK 写法上是一样的,但是代码已经无比清爽。 字符串操作 作为开发中最长使用的数据类型,字符串操作的增强可以让开发更加高效。 字符拼接 JDK 8 中其实已经内置了字符串拼接方法,但是它只是简单的拼接,没有额外操作,比如过滤掉 null 元素,去除前后空格等。先看一下 JDK 8 中字符串拼接的几种方式。 // JDK 方式一 ArrayList<string> list = Lists.newArrayList("a", "b", "c", null); String join = String.join(",", list); System.out.println(join); // a,b,c,null // JDK 方式二 String result = list.stream().collect(Collectors.joining(",")); System.out.println(result); // a,b,c,null // JDK 方式三 StringJoiner stringJoiner = new StringJoiner(","); list.forEach(stringJoiner::add); System.out.println(stringJoiner.toString()); // a,b,c,null 可以看到 null 值也被拼接到了字符串里,这有时候不是我们想要的,那么使用 Guava 有什么不一样呢? ArrayList<string> list = Lists.newArrayList("a", "b", "c", null); String join = Joiner.on(",").skipNulls().join(list); System.out.println(join); // a,b,c String join1 = Joiner.on(",").useForNull("空值").join("旺财", "汤姆", "杰瑞", null); System.out.println(join1); // 旺财,汤姆,杰瑞,空值 可以看到使用 skipNulls() 可以跳过空值,使用 useFornull(String) 可以为空值自定义显示文本。 字符串分割 JDK 中是自带字符串分割的,我想你也一定用过,那就是 String 的 split 方法,但是这个方法有一个问题,就是如果最后一个元素为空,那么就会丢弃,奇怪的是第一个元素为空却不会丢弃,这就十分迷惑,下面通过一个例子演示这个问题。 String str = ",a,,b,"; String[] splitArr = str.split(","); Arrays.stream(splitArr).forEach(System.out::println); System.out.println("------"); /** * * a * * b * ------ */ 你也可以自己测试下,最后一个元素不是空,直接消失了。 如果使用 Guava 是怎样的操作方式呢?Guava 提供了 Splitter 类,并且有一系列的操作方式可以直观的控制分割逻辑。 String str = ",a ,,b ,"; Iterable<string> split = Splitter.on(",") .omitEmptyStrings() // 忽略空值 .trimResults() // 过滤结果中的空白 .split(str); split.forEach(System.out::println); /** * a * b */ 缓存 在开发中我们可能需要使用小规模的缓存,来提高访问速度。这时引入专业的缓存中间件可能又觉得浪费。现在可以了, Guava 中提供了简单的缓存类,且可以根据预计容量、过期时间等自动过期已经添加的元素。即使这样我们也要预估好可能占用的内存空间,以防内存占用过多。 现在看一下在 Guava 中缓存该怎么用。 @Test public void testCache() throws ExecutionException, InterruptedException { CacheLoader cacheLoader = new CacheLoader<string, animal>() { // 如果找不到元素,会调用这里 @Override public Animal load(String s) { return null; } }; LoadingCache<string, animal> loadingCache = CacheBuilder.newBuilder() .maximumSize(1000) // 容量 .expireAfterWrite(3, TimeUnit.SECONDS) // 过期时间 .removalListener(new MyRemovalListener()) // 失效监听器 .build(cacheLoader); // loadingCache.put("狗", new Animal("旺财", 1)); loadingCache.put("猫", new Animal("汤姆", 3)); loadingCache.put("狼", new Animal("灰太狼", 4)); loadingCache.invalidate("猫"); // 手动失效 Animal animal = loadingCache.get("狼"); System.out.println(animal); Thread.sleep(4 * 1000); // 狼已经自动过去,获取为 null 值报错 System.out.println(loadingCache.get("狼")); /** * key=猫,value=Animal{name='汤姆', age=3},reason=EXPLICIT * Animal{name='灰太狼', age=4} * key=狗,value=Animal{name='旺财', age=1},reason=EXPIRED * key=狼,value=Animal{name='灰太狼', age=4},reason=EXPIRED * * com.google.common.cache.CacheLoader$InvalidCacheLoadException: CacheLoader returned null for key 狼. */ } /** * 缓存移除监听器 */ class MyRemovalListener implements RemovalListener<string, animal> { @Override public void onRemoval(RemovalNotification<string, animal> notification) { String reason = String.format("key=%s,value=%s,reason=%s", notification.getKey(), notification.getValue(), notification.getCause()); System.out.println(reason); } } class Animal { private String name; private Integer age; @Override public String toString() { return "Animal{" + "name='" + name + '\'' + ", age=" + age + '}'; } public Animal(String name, Integer age) { this.name = name; this.age = age; } } 这个例子中主要分为 CacheLoader、MyRemovalListener、LoadingCache。 CacheLoader 中重写了 load 方法,这个方法会在查询缓存没有命中时被调用,我这里直接返回了 null,其实这样会在没有命中时抛出 CacheLoader returned null for key 异常信息。 MyRemovalListener 作为缓存元素失效时的监听类,在有元素缓存失效时会自动调用 onRemoval 方法,这里需要注意的是这个方法是同步方法,如果这里耗时较长,会阻塞直到处理完成。 LoadingCache 就是缓存的主要操作对象了,常用的就是其中的 put 和 get 方法了。 总结 上面介绍了我认为最常用的 Guava 功能,Guava 作为 Google 公司开源的 Java 开发核心库,个人觉得实用性还是很高的。引入后不仅能快速的实现一些开发中常用的功能,而且还可以让代码更加的优雅简洁。我觉得适用于每一个 Java 项目。Guava 的其他的功能你也可以自己去发现。它的 Github 地址是:https://github.com/google/guava. 参考 https://github.com/google/guava/wiki 订阅 >文章已经收录在 Github.com/niumoo/JavaNotes ,欢迎Star和指教。更有一线大厂面试点,Java程序员需要掌握的核心知识等文章,也整理了很多我的文字,欢迎 Star 和完善,希望我们一起变得优秀。 文章每周持续更新,有帮助可以点个「赞」或「分享」,都是支持,我都喜欢! 要实时关注更新的文章以及分享的干货,可以关注 未读代码 公众号(下方二维码)或者我的网站。 </string,></string,></string,></string,></string></string></string></string,></string></string></string,></string></string></string,></string,></string></string></string></string></string></string></string></object></comparable,></object,></object,></string></string></string></string></string></string></string></string></string></string></string></string></string></string></string></string>

优秀的个人博客,低调大师

Gradle 6.6 发布,引入配置缓存特性,大幅提升构建性能

Gradle 6.6 发布了。Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建工具,支持依赖管理和多项目,类似Maven,但比之简单轻便。它使用一种基于Groovy的特定领域语言来声明项目设置,而不是传统的XML。 此版本最大亮点是引入了一个实验性选项:配置缓存(Configuration caching),它是一个主要的性能优化特性,可以使 Gradle 跳过构建的配置阶段,并尽快开始执行任务。 配置缓存 在运行任何任务之前,Gradle 需要运行配置阶段。当前,这是在每次构建调用时完成的,并且会产生大量的开销,尤其是在大型项目中。 配置缓存通过缓存配置阶段的结果并将其重新用于后续构建,从而可以显著提高构建性能。使用配置缓存,Gradle 可以在不影响构建配置的任何内容发生变化的情况下完全跳过配置阶段,如下所示: 此外,启用配置缓存后,Gradle 能够优化任务执行,并默认情况下并行执行更多任务。 目前该特性处于高度试验阶段,默认情况下不启用或建议用于生产环境。可以通过--configuration-cache在命令行上提供参数或将其添加到运行配置中来启用此实验特性。 标准化的运行时类路径改善缓存命中率 对于最新检查和构建缓存,Gradle 需要确定两个任务输入属性是否具有相同的值。为此,Gradle 首先将两个输入标准化,然后比较结果。 现在,运行时类路径分析将检查清单META-INF文件和属性文件,而忽略对注释、空格和顺序差异的更改。此外还可以有选择地忽略不影响运行时类路径的属性。 normalization { runtimeClasspath { metaInf { ignoreAttribute("Implementation-Version") ignoreProperty("timestamp") } } } 类路径上的任何 ZIP 文件被重新生成并且仅因不重要的值或注释而不同的情况下,将提高生成高速缓存命中的可能性。这种规范化最有用的最常见情况是 JAR 文件,不过它也可以被应用于类路径上的任何 ZIP 文件,例如 AAR、WAR 和 APK 文件。 处理用户提供的凭证 构建有时会要求用户提供凭据,例如,为了发布工件,可能需要凭证才能与工件存储库进行身份验证。将凭据保留在构建脚本之外是一个好习惯。 此版本提供了用于凭证的新 API,该凭证通过建立约定以使用 Gradle 属性提供凭证来简化凭证的使用,Gradle 属性可以作为命令行参数、环境变量或gradle.properties文件中的值提供给构建环境。当 Gradle 知道某个时候该版本将需要凭证并且凭证已丢失时,它还会执行“快速失效”。 从此版本开始,可以轻松地将用于身份验证的凭证外部化到工件存储库: repositories { maven { name = 'mySecureRepository' credentials(PasswordCredentials) // url = uri(<<some repository url>>) } } mySecureRepository将在 Gradle 属性中搜索名称为mySecureRepositoryUsername和mySecureRepositoryPassword的凭据。 同时还可以直接使用新的provider API向外部工具提供凭据: tasks.register('login', Exec) { def loginProvider = providers.credentials(PasswordCredentials, 'login') inputs.property('credentials', loginProvider) doFirst { PasswordCredentials loginCredentials = loginProvider.get() // use credentials } } 上面的凭据将在 Gradle 属性中使用名称loginUsername和loginPassword进行搜索。 此外,此版本还有其它改进,包括对 Java 编译 --release 标志的支持、文件系统监视的稳定性改进、依赖管理的改进,以及 bug 修复等,详情查看更新说明:https://docs.gradle.org/6.6/release-notes.html

优秀的个人博客,低调大师

WGCLOUD 监控系统,升级数据扫描机制,提升性能

WGCLOUD基于java语言开发,是微服务架构构建监控系统,支持高并发高性能高可用,核心模块包括:服务器集群监控,ES集群状态监控,CPU监控,内存监控,数据监控(mysql,postgresql,oracle,sqlserver,db2),服务心跳检测,应用进程管理,磁盘IO监控,系统负载监控,监控告警信息推送。 此次更新,新增数据监控间隔时间配置,服务接口监控间隔时间配置,使之更快更灵活。根据个人需求酌情修改扫描时间,时间间隔越短,监控更实时,但是server压力相应会加大,根据服务器配置观察调整。 base: #登陆账号admin的密码 admindPwd: 111111 #通信token,agent端和此保持一致 wgToken: wgcloud #是否开启公众看板,yes开启,no关闭,公众看板页面无需登陆 dashView: yes #数据表监控间隔,单位毫秒,默认60分钟 dbTableTimes: 3600000 #服务接口监控间隔,单位毫秒,默认10分钟 heathTimes: 600000

优秀的个人博客,低调大师

WGCLOUD 监控系统更新,重构告警信息开关组,提升性能

WGCLOUD基于java语言开发,是微服务架构构建监控系统,支持高并发高性能高可用,核心模块包括:服务器集群监控,ES集群状态监控,CPU监控,内存监控,数据监控(mysql,postgresql,oracle,sqlserver,db2),服务心跳检测,应用进程管理,磁盘IO监控,系统负载监控,监控告警信息推送。 此次更新,新增告警信息推送的开关组合,可以在配置文件中开启和关闭,灵活配置。 #告警配置 mail: #告警邮件总开关,yes开启,no关闭 allWarnMail: yes #监控主机内存使用率%报警值,超过此值即发送邮件报警 memWarnVal: 98 #监控主机cpu使用率%报警值,超过此值即发送邮件报警 cpuWarnVal: 98 #内存告警邮件,yes开启,no关闭。总开关开启后,此处设置才会生效。以下开关均遵循此规则。 memWarnMail: yes #CPU告警邮件,yes开启,no关闭 cpuWarnMail: yes #主机下线告警邮件,yes开启,no关闭 hostDownWarnMail: yes #进程下线告警邮件,yes开启,no关闭 appDownWarnMail: yes #服务接口告警邮件,yes开启,no关闭 heathWarnMail: yes 码云源码下载:https://gitee.com/wanghouhou/wgcloud GITHUB源码下载:https://github.com/tianshiyeben/wgcloud 安装包下载:http://www.wgstart.com

优秀的个人博客,低调大师

内核调优 | 如何提升Elasticsearch master调度性能40倍

作者:兴丰__阿里云Elasticsearch团队 高级开发工程师 本文字数:1299阅读时间:2~5分钟 以下是正文 背景 我们在协助某Elasticsearch用户准备将自建集群迁往阿里云Elasticsearch的过程中发现,自建集群从ES6.3.2版本升级到7.4.0版本后,master变得特别卡,创建索引和删除耗时超过1分钟。该集群当时有3个专有主节点、10个热节点、2个冷节点,超过5万个shard,绝大部分索引/shard都是关闭的,当索引过期移动到冷节点就close掉,需要查询时再调用open命令打开。同时,在试过6.x到7.x的多个版本后,发现自7.2.0后的版本都有问题,而即使把专有主节点升级到32c64g的规格,还是不行。 思考 由于是自建的线上生产集群,登录机器和查看集群状态极为不便,也有一定的风险。因此计划先从Elas

优秀的个人博客,低调大师

自定义 ForkJoinPool 提升并行流 ParallelStream 执行速度

简介 在 java8 中 添加了流Stream,可以让你以一种声明的方式处理数据。使用起来非常简单优雅。ParallelStream 则是一个并行执行的流,采用 ForkJoinPool 并行执行任务,提高执行速度。 下面我们看看2个简单的示例: 示例1 (list) Arrays.asList(1,2,3,4,5,6) .parallelStream() .forEach((value) -> { String name = Thread.currentThread().getName(); System.out.println("示例1 Thread:" + name + " value:" + value); }); 示例2 (array) Stream.o

优秀的个人博客,低调大师

Flutter提升开发效率的一些方法和工具

Flutter的环境搭配完之后,就开始Flutter的开发,下面的一些工具和方法,可以省下一些时间。 自己在用的,暂时想到的,就是这些了,总结一下。 1.JSON解析快速生成实体类根据接口返回的数据,编写实体类,添加两个方法。 fromJson()方法是可以聪一个Map中构造出一个User的实例,toJson()方法,可以将一个实例转化为Map。如果接口返回的数据比较复杂点,那么手动写起来就会很麻烦。这个时候可以利用json_serializable来帮你自动生成实体类的一些代码,还有利用caijinglong.github.io/json2dart/i…来快速生成相关代码。 将json数据复制到这个网站上,就会生成相关的代码,只需要将这些代码复制到项目中的文件就行了, 最后在我们的项目根目录下运行flutter packages pub run build_runner build,我们可以在需要时为我们的model生成json序列化代码 。 注意:要先在pubspec.yaml文件里面添加: 每个类最后面生成的with _$UserSerializerMixin,这部分可以去掉,不去掉的话,好像生成会有问题,反正我是去掉了,没什么影响。2.代码模板最简单的一个例子,就是在写一个有状态StatefulWidget的时候,要手动继承StatefulWidget,重写createState方法,再创建一个相应的State类并重写build方法。会写到你吐血。 这个时候就需要一些代码模板,帮你快速生成代码。 反正百度一下肯定有些导入Flutter代码模板的教程。 比如直接打出stf,就可以自动提示生成StatefulWidget的代码了。 3.Asset资源文件的导入Flutter中,常见类型的asset包括静态数据(例如JSON文件),配置文件,图标和图片(JPEG,WebP,GIF,动画WebP / GIF,PNG,BMP和WBMP)。 一般导入的资源都要在pubspec.yaml文件中按照下面的方式,一个一个进行声明,应用程序才能获取到。 改进方法:要包含asset文件下面的所有资源,直接用下面这样方法,这样的话,只在这个目录里的文件会被包含进来。 4.Flutter Outline工具,主要用于视图的预览,还有其他功能在编写布局的时候,可以看到Flutter Outline界面,会实时地更新所写的布局层次,方便查看。 除了视图的预览,还有其他的功能。 就是右键某一个widget,可以根据提示框,快速帮你在这个widget的外面包装一层比如padding之类的代码。这个功能有时候挺方便的。Extract method的作用是:可以把某一个widget控件的代码,帮你封装成一个方法。不用你去手动地去找出一个widget的全部代码,再自己拉到某一个方法内。 另一方面,也可以方便地看出这个widget的相关代码,比如要复制操作起来也比较方便。5.拖动widget自动生成相关代码有一个网站:flutterstudio.app/ 可以拖动widget到模拟器中,就可以生成相关的布局代码,自己手动复制粘贴就可以了。 原文发布时间为:2018-12-8本文作者:Android开发中文站本文来自云栖社区合作伙伴“ Android开发中文站”,了解相关信息可以关注“AndroidChinaNet”微信公众号

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册