Java8相关底层

别再让PyCharm吃光你的C盘!保姆级教程:安全迁移config、plugins和remote sources到D盘 本文提供了一份详细的PyCharm配置与缓存文件迁移指南,帮助开发者将config、plugins和remote sources等占用大量C盘空间的文件安全转移到D盘。通过修改data.properties文件和正确迁移顺序,确保PyCharm功能不受影响,同时释放宝贵的系统盘空间。 阅读详情

Java8是往并行方向走的。由面向对象到函数式编程。

在支持函数式编程的同时还可以支持面向对象的开发。

在JDK1.8里面,接口里面可以有实现方法的!默认方法,default。实现这个接口。

接口里面可以有静态方法

注意Lambda表达式的类型势函数。但是在Java中,Lambda表达式是对象!他们必须依赖于一类特别的对象类型-函数式接口

关于Function<T,R>接口

public class FunctionTest {
    public static void main(String[] args) {
        FunctionTest functionTest = new FunctionTest();
        //传递行为
        System.out.println(functionTest.compute(1, value -> {return 10 * value;}));
    }

    public int compute (int a, Function<Integer, Integer> function){
        // 实现,由调用者去实现之
        int result = function.apply(a);
        return  result;
    }
}

解析:

单独吧Lambda抽取出来:

public class FunctionTest {
    public static void main(String[] args) {
        //先把Lambda定义好
        Function<Integer, Integer> function = value -> value * 2;
        FunctionTest functionTest =  new FunctionTest();
        System.out.println(functionTest.compute(5, function));

    }

    public int compute(int a, Function<Integer, Integer> function){
        int result = function.apply(a);
        return result;
    }

}

多个function之间的串联与先后关系的指定:

public class FunctionTest {
    public static void main(String[] args) {
        FunctionTest functionTest = new FunctionTest();
        System.out.println(functionTest.compute1(2, value -> value * 3, value -> value *value));
        System.out.println(functionTest.compute2(2, value -> value * 3, value -> value *value));
    }

    public int compute1(int a, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {
        return function1.compose(function2).apply(a);
    }

    public int compute2(int a, Function<Integer, Integer> function1, Function<Integer, Integer> function2) {
        return function1.andThen(function2).apply(a);
    }
}

compose源码:

对比上面的例子,先执行function2 然后将结果赋值给function1去执行   

andThen是相反的。

所以,对于 R apply(T t);  要想实现两个输入一个输出,是做不到的。可以通过 BiFunction得到。

public class FunctionTest {
    public static void main(String[] args) {
        FunctionTest functionTest = new FunctionTest();
        System.out.println(functionTest.compute4(2,3, (value1, value2) -> value1 + value2, value -> value * value));
    }

    public int compute4(int a, int b, BiFunction<Integer, Integer, Integer> biFunction, Function<Integer, Integer> function){
        return biFunction.andThen(function).apply(a,b);
    }
}

Predicate

filter的参数类型就是Predicate!

函数式编程提供了更高层次的抽象化:

 test() 名字都是抽象的,不具体。比较宏观。

public class FunctionTest {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
        FunctionTest functionTest = new FunctionTest();
        functionTest.conditionFilter(list, item -> item % 2 == 0);
    }

   public void conditionFilter(List<Integer> list, Predicate<Integer> predicate){
        for (Integer integer : list){
           if (predicate.test(integer)){
               System.out.println(integer);
           }
        }
   }
} 

对于Predicate的default函数:

public class FunctionTest {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
        FunctionTest functionTest = new FunctionTest();
        functionTest.conditionFilter(list, item -> item % 2 == 0, item -> item < 6);
    }

    public void conditionFilter(List<Integer> list, Predicate<Integer> predicate1, Predicate<Integer> predicate2){
        for (Integer integer : list){
            // and 返回的是Predicate! 所以继续 .test
            if (predicate1.and(predicate2).test(integer)){
//                if (predicate1.or(predicate2).test(integer)){
                if (predicate1.negate().test(integer)){  // 取反。满足条件后剩下的
            // 如果两个都满足
                System.out.println(integer);
            }
        }
   }
}

静态方法: 返回的也是Predicate 

作用就是判断两个参数是否相等。

public class FunctionTest {
    public static void main(String[] args) {
        FunctionTest functionTest = new FunctionTest();
        //isEqual传进来的是test 然后和参数 “test”比较
        System.out.println(functionTest.isEqual(new Date()).test(new Date()));
    }
    public Predicate<Date> isEqual(Object object){
        return Predicate.isEqual(object);
    }
}

Comparator 还是个函数式接口。里面有好几个函数式接口

结合BinaryOperator

Optional  是个容器,可能包含空值,非空值

public class FunctionTest {
    public static void main(String[] args) {
//        Optional<String> optional = Optional.empty();
        Optional<String> optional = Optional.of("valueTest");
        optional.ifPresent(item -> System.out.println(item));
        System.out.println(optional.orElse("world"));
        System.out.println(optional.orElseGet( () -> "hello"));
    }

}
public class FunctionTest {
    public static void main(String[] args) {

        Employee employee1 = new Employee();
        employee1.setName("123");

        Employee employee2 = new Employee();
        employee2.setName("456");

        Company company = new Company();
        company.setName("c1");

        List<Employee> employees = Arrays.asList(employee1, employee2);

        company.setEmployees(employees);

        List<Employee> result = company.getEmployees();

//        if (result != null){
//            return result;
//        }else {
//            return new ArrayList<>();
//        }
        //一行代码搞定
        Optional<Company> optional = Optional.ofNullable(company);
        System.out.println(optional.map( item -> item.getEmployees()).orElse(Collections.emptyList()));
    }

}

注意 Optional类型,不用做参数类型!  因为没有序列化!

作为返回类型,规避null! 

方法引用类似于函数指针。‘’

Remember:

           function 接收一个 返回一个   

           Supplier 只返回不接受

总结方法引用分4类:

   1. 类名::静态方法名

   2. 引用名(对象名)::实例方法名

   3.  类名::实例方法名

   4. 构造方法引用:: 类名::new

流有个好处,支持并行化,对一个集合进行迭代,流可以并行,多个线程进行处理。对于多核处理性能大大提升。

public class FunctionTest {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("a", "b", "c", "d");
        String[] strings = stream.toArray(length -> new String[length]);
        Arrays.asList(strings).forEach(System.out::println);
    }

}

改造成Lambda表达式构造函数引用:  通过构造函数引用的方式将数组传递进去

public class FunctionTest {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("a", "b", "c", "d");
        String[] strings = stream.toArray(String[]::new);
        Arrays.asList(strings).forEach(System.out::println);
    }

}

public class FunctionTest {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("a", "b", "c", "d");
        List<String> list1 = stream.collect(() -> new ArrayList(),
                (theList, item) -> theList.add(item),
                (theList1, theList2) -> theList1.addAll(theList2));

        //方法二
        List<String> list2 = stream.collect(LinkedList::new, LinkedList::add, LinkedList::addAll);
        list.stream().forEach(System.out::println);
    }

}
public class FunctionTest {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("a", "b", "c", "d");
        String str = stream.collect(Collectors.joining()).toString();
        System.out.println(str);
    }
}

flatMap去操作:

public class FunctionTest {
    public static void main(String[] args) {
        Stream<List<Integer>> listStream = Stream.of(Arrays.asList(1), Arrays.asList(2, 3), Arrays.asList(4, 5, 6));
        //每个List转成Stream
        listStream.flatMap( theList -> theList.stream())
                .map( item -> item * item).forEach(System.out::println);
    }
}

正确使用Optional:

public class FunctionTest {
    public static void main(String[] args) {
        Stream<String> stream = Stream.generate(UUID.randomUUID()::toString);
        //返回的是个Optional可以调用get方法。 流里面的第一个元素为啥返回Optional。避免异常。如果流里面没有元素呢?规避之
        System.out.println(stream.findFirst().get());
        //如果存在元素的话...
        stream.findFirst().ifPresent(System.out::println);
        //可以创建空的流
        Stream<String> stream1 = Stream.empty();
        stream1.findFirst().ifPresent(System.out::println);

    }
}
public class FunctionTest {
    public static void main(String[] args) {

        Stream<Integer> stream = Stream.iterate(1, item -> item + 2).limit(6);
        IntSummaryStatistics summaryStatistics = stream.filter(item -> item > 2)
                .mapToInt(item -> item * 2).skip(2).limit(2).summaryStatistics();

        System.out.println( summaryStatistics.getMax());
        System.out.println( summaryStatistics.getMin());
    }
}

例子:Map: 中间操作,延迟操作。遇到终止操作时候才会执行之

public class FunctionTest {
    public static void main(String[] args) {
        List<String> list = Arrays.asList("hello", "world", "how are you");
        list.stream().map(
                item -> {
                    String result = item.substring(0, 1).toUpperCase() + item.substring(1);
                    System.out.println("----->");
                    return result;
                }
        ).forEach( System.out::println);
    }
}

Map和flatMap

 public static void main(String[] args) {

      List<String> list = Arrays.asList("hello welcome", "world hello");
//返回的List string类型的数组 四个数组对象不是不同的!
        List<String[]> result = list.stream()
// <R> Stream<R> map(Function<? super T, ? extends R> mapper);
.map(item -> item.split(" ")).distinct().collect(Collectors.toList());
result.forEach(
item -> Arrays.asList(item).forEach(System.out::println)
);
// flatMap System.out.println("----->flatMap"); List<String> resultFlatMap = list.stream().map(item -> item.split(" ")) //<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
          //将数组类型 转成 String类型 .flatMap(Arrays::stream) // 接收的是一个数组类型。返回Stream类型。这样返回四个Stream。 调用FlatMap把四个Stream合并成一个! .distinct().collect(Collectors.toList()); resultFlatMap.forEach(System.out::println); }

 

分析 FlatMap将结果打平了,结果放在一个流里面。 

上述对于 FlatMap的使用, 首先map映射成字符串数组类型的内容, 然后将字符串数组打平。打平成一个Stream。即: 将 Stream<Strimg[]>  ------> Stream<String>

public class FunctionTest {
    public static void main(String[] args) {

        List<String> list1 = Arrays.asList("你好", "哈哈");
        List<String> list2 = Arrays.asList("zhangsan", "lisi", "wangwu");

        List<String> result = list1.stream().flatMap(item -> list2.stream().map(item2 -> item + " " + item2)).collect(Collectors.toList());
        result.forEach(System.out::println);
    }
}

 Stream:

    和迭代器不同的是,Stream可以并行化操作,迭代器只能命令式、串行化操作

    当使用串行方式遍历时,每特item读完后再读下一个

    使用并行去遍历时,数据会被分成多段,其中每一个都在不同的线程中处理,然后将结果一起输出。

    Stream的并行操作依赖于Java7中引入的Fork/Join框架。任务分解成小任务。

    集合关注的是数据与数据存储

    流关注的是数计算,流与迭代器类似的一点是: 流复发重复使用或者消费的。

   中间操作都会返回一个Stream对象,比如 Stream<Integer> Stream<Strimg>  比如 mapToInt返回 Stream<Integer>

public class FunctionTest {
    public static void main(String[] args) {

        Employee employee1 = new Employee("a");
        Employee employee2 = new Employee("a");
        Employee employee3 = new Employee("b");
        Employee employee4 = new Employee("c");
        List<Employee> list = Arrays.asList(employee1, employee2, employee3, employee4);
        Map<String, Long> nameCountMap = list.stream().collect(Collectors.groupingBy(Employee::getName, Collectors.counting()));
        System.out.println(nameCountMap);

    }
}

 list.stream().collect(Collectors.groupingBy(Employee::getName, Collectors.averagingDouble(Employee::getScore));

分组:group by

分区: partition by 区别group by 只能分两组 ,比如 true false。 90以上及格,以下不及格

collect是Stream提供的一个方法。Collector作为Collect方法的参数。Collector接口非常重要,分析之:

Collector是一个接口,文档解释“它是一个可变的汇聚操作,将输入元素累积到一个可变的结果容器中;它会在所有元素处理完毕之后,将累积结果转换为一个最终的表示(这是一个可选操作。支持串行并行两种方式执行。 

注意: 并行不一定比串行块,因为并行涉及到线程切换。比如cpu 2核的,生成四个线程。势必四个线程去增强这两个核心,会存在上下文切换。

Collectors本身提供了关于Collectors的常见汇聚实现,Collectors本身是一个工厂。

Collector是由四个元素组成的

combiner函数,有四个线程同时去执行,那么就会生成四个部分结果。然后合并成一个。用在并行流的场景。 

为了确保串行与并行操作的结果等价性,Collector函数需要满足两个条件,identity(同一性)与associativity(结合性)。

public interface Collector<T,A,R>    T:集合或者流中的每个元素类型, A可变容器类型, R:结果类型

  ·

public class FunctionTest {
    public static void main(String[] args) {

        Employee employee1 = new Employee("a", 12);
        Employee employee2 = new Employee("a", 23);
        Employee employee3 = new Employee("b", 43);
        Employee employee4 = new Employee("c", 34);
        List<Employee> employees = Arrays.asList(employee1, employee2, employee3, employee4);

        String collect1 = employees.stream().map(Employee::getName).collect(Collectors.joining(","));

        //连续分组
        Map<Integer, Map<String, List<Employee>>> collect = employees.stream()
                .collect(Collectors.groupingBy(Employee::getScore, Collectors.groupingBy(Employee::getName)));
        
        //分区
        Map<Boolean, List<Employee>> collect2 = employees.stream().collect(Collectors.partitioningBy(e -> e.getScore() > 3));
        
        //连续分区
        Map<Boolean, Map<Boolean, List<Employee>>> collect3 = employees.stream().collect(Collectors.partitioningBy(e -> e.getScore() > 80, Collectors.partitioningBy(e -> e.getScore() > 5)));

        //综合实战
        Map<Boolean, Long> collect4 = employees.stream().collect(Collectors.partitioningBy(employee -> employee.getScore() > 90, Collectors.counting()));

        Map<String, Employee> collect5 = employees.stream().collect(Collectors.groupingBy(Employee::getName,
                // 收集然后XXX
                Collectors.collectingAndThen(Collectors.minBy(Comparator.comparingInt(Employee::getScore)),
                        Optional::get)));

    }
}

排序:

 Collector.sort() 本质上是调用 list.sort()

public class FunctionTest {
    public static void main(String[] args) {

        List<String> list = Arrays.asList("helloWorld", "nihao", "java");
        Collections.sort(list, (item1, item2) -> {return (item1.length() - item2.length());});
        System.out.println(list);
        //当lambda没法推断类型时候,指定下
        Collections.sort(list, Comparator.comparingInt((String item) -> item.length()).reversed());
        list.sort(Comparator.comparingInt(String::length).reversed());
        list.sort(Comparator.comparingInt((String item) -> item.length()).reversed());
        //不区分大小写的排序,两个排序规则. 先升序,然后XXX.两个比较规则,第一个相同就调用第二个方法。
        Collections.sort(list, Comparator.comparingInt(String::length).thenComparing(String.CASE_INSENSITIVE_ORDER));
        Collections.sort(list, Comparator.comparingInt(String::length).thenComparing( (item1, item2) -> item1.toLowerCase().compareTo(item2.toLowerCase())));
        Collections.sort(list, Comparator.comparingInt(String::length).thenComparing(Comparator.comparing(String::toLowerCase)));
        //长度希望等的,才需要进行第二次比较。小写进行比较,小写逆序。
        Collections.sort(list, Comparator.comparingInt(String::length).thenComparing(Comparator.comparing(String::toLowerCase, Comparator.reverseOrder())));
        Collections.sort(list, Comparator.comparingInt(String::length).reversed().thenComparing(Comparator.comparing(String::toLowerCase, Comparator.reverseOrder())));
        //多级排序
        Collections.sort(list, Comparator.comparingInt(String::length).reversed()
                // 相同的(比较结果为0的,继续使用下面的方法)
                .thenComparing(Comparator.comparing(String::toLowerCase, Comparator.reverseOrder()))
                // 是否起作用,取决于前面的比较情况结果
                .thenComparing(Comparator.reverseOrder()));
    }
}

定义实现自己的收集器:

/**
 * 1.实现接口时候,要定义好泛型
 * 2.
 */
public class MySetCollector<T> implements Collector<T, Set<T>, Set<T>> {

    /**
     * 提供一个空的容器,供accumulator 后续方法调用
     * @return
     */
    @Override
    public Supplier<Set<T>> supplier() {
        System.out.println("-----> supplier");
        return HashSet<T>::new;
    }

    /**
     * 累加器类型的,接收两个参数不返回值
     * @return
     */
    @Override
    public BiConsumer<Set<T>, T> accumulator() {
        System.out.println("-----> accumulator");
        //通过方法引用的方式返回了一个 BiConsumer 对象
//        return Set<T>::add;
     return (set, item) -> set.add(item);
    }

    /**
     * 将并行流,多个线程所执行的结果合并起来
     * @return
     */
    @Override
    public BinaryOperator<Set<T>> combiner() {
        // 把一个部分结果,添加到另外一个部分结果中
        System.out.println("------> combiner");
        return (set1, set2) -> {
            set1.addAll(set2);
            return set1;
        };
    }

    /**
     * 多线程情况下,最后一步要执行的。返回最终的结果类型。返回结果容器给用户。
     * @return
     */
    @Override
    public Function<Set<T>, Set<T>> finisher() {
     //   return t -> t;
        return Function.identity();
    }

    /**
     * 返回一个set集合,表示当前的收集器诸多独特性。
     * @return
     */
    @Override
    public Set<Characteristics> characteristics() {
        System.out.println("----->characteristics");
        // 直接返回一个不可变的集合,参数为指定的特性
        return Collections.unmodifiableSet(EnumSet.of(IDENTITY_FINISH, UNORDERED));
    }

    public static void main(String[] args) {
        List<String> list = Arrays.asList("hello", "world", "welcome", "hello");
        Set<String> collect = list.stream().collect(new MySetCollector<>());
        System.out.println(collect);
    }
}

 

 看下面例子:

public class MySetCollector2<T> implements Collector<T,Set<T>, Map<T,T>> {


    @Override
    public Supplier<Set<T>> supplier() {
        System.out.println("supplier invoked");
        return HashSet::new;
    }

    @Override
    public BiConsumer<Set<T>, T> accumulator() {
        System.out.println("accumulator invoked");
        return (set, item) -> {
            set.add(item);
        };
    }

    @Override
    public BinaryOperator<Set<T>> combiner() {
        System.out.println("combiner invoked");
        return (set1, set2) -> {
            set1.addAll(set2);
            return set1;
        };
    }

    @Override
    public Function<Set<T>, Map<T, T>> finisher() {
        System.out.println("finisher invoked");
        return set -> {
            Map<T,T> map = new HashMap<>();
            set.stream().forEach(
                    item -> map.put(item, item)
            );
            return map;
        };
    }

    @Override
    public Set<Characteristics> characteristics() {
        System.out.println("characteristics invoked!");
        return Collections.unmodifiableSet(EnumSet.of(Characteristics.UNORDERED));
    }

    public static void main(String[] args) {
        List<String> list = Arrays.asList("hello", "world", "welcome", "a", "b", "c");
        Set<String> set = new HashSet<>();
        set.addAll(list);
        System.out.println("set"+ set);

        Map<String, String> collect = set.stream().collect(new MySetCollector2<>());
        System.out.println(collect);
    }
}

收集器:

   对于Collectors惊天工厂类来说,其实现一共分为两种情况:

  1.     通过ColletcorImpl来实现
  2.     通过reduceing方法来实现(reducing方法本身又是通过CollectorImpl来实现) 

关于toList()

 public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }
IIC协议常见误区解析:从时序图到实际波形(附逻辑分析仪实测) 本文深入解析IIC协议在实际应用中的常见误区,从理想时序图到逻辑分析仪实测波形的差异,揭示通信故障的根本原因。通过硬件设计优化、软件时序调优和高级调试技巧,帮助开发者有效规避IIC通信中的隐形陷阱,提升系统稳定性。 阅读详情

相关推荐

米哈游 AI产品经理面试题精选:10道高频考题+答案解析(附PDF)

米哈游是全球知名游戏开发商,以《原神》《崩坏》系列著称,专注二次元文化与AI技术创新。本文整理了10道AI产品经理面试题,涵盖Transformer架构、智能NPC设计、机器学习应用、AIGC产品规划等核心领域。题目既考察技术理解(如RAG原理、多模态模型),又关注产品落地(游戏平衡性优化、伦理安全),同时强调跨团队协作能力。参考答案均结合米哈游业务场景,体现技术驱动与玩家体验并重的产品思维,展现AI在游戏行业的创新应用前景。

ZHHHHH15的博客 682

java 8 详解_JAVA 8 的底层详解

JAVA 8 的新特性Java 8 早在2014年3月份就已经有了,然而这是一次大的更新,如今的安卓框架就在使用java 8 的 Lambda表达式,如今正被越来越多的人发现它的优点与好处,也成为了未来的趋势。Java 8 的优点:速度更快代码更少(增加新语法Lambda 表达式)强大的Stream API便于并行最大化减少空指针异常 Optional首先速度更快体现在很多方面,比如对于底层的数据...

weixin_39616222的博客 275

数字信号完整性分析:眼图原理与应用指南

眼图是数字信号完整性分析中的核心工具,通过将数字信号在时间域上多次叠加形成类似人眼的图形,直观反映信号质量。其原理基于时钟恢复和波形叠加,能有效展示信号的统计特性,包括上升/下降时间、过冲/下冲等关键参数。在高速数字电路设计中,眼图分析对于评估信号完整性、调试抖动问题至关重要,广泛应用于DDR接口、高速串行链路等场景。通过合理设置示波器参数和采用均衡技术,工程师可以优化眼图表现,提升系统可靠性。本文结合DDR4内存等实际案例,详解眼图的测量方法与常见问题解决方案。

weixin_35459464的博客 344

java8 arraylist底层

java arraylist底层实现原理

weixin_47993432的博客 179

【网络安全的神秘世界】解决dvwa靶场报错:Illegal mix of collations for operation ‘UNION‘

我的 information_schema 使用的是 utf8_general_ci。请根据您的实际情况调整字符集。这通常意味着在执行 UNION 操作时,不同字符集的数据发生了混合,导致冲突。修改字符集设置后,重启 MySQL 服务以应用更改,再次测试一下发现成功。查看 information_schema 的字符集。修改 DVWA 数据库字符集。

菜鸟小羊的博客 2044

FPGA编译加速实战:6大可落地的Vivado优化策略

FPGA编译本质上是NP-hard约束满足问题求解,而非传统软件编译;Vivado作为时序驱动的硬件实现工具链,其耗时瓶颈集中在Implementation阶段的布局布线(PnR)与逻辑优化。理解这一原理,才能跳出‘加线程’‘升版本’等表面优化,转向精准时序约束、增量编译、物理锚点控制、IP配置精简等工程级干预。这些技术手段直接作用于Vivado的Tcl执行流与底层求解空间,显著压缩搜索范围、减少无效迭代——尤其适用于Zynq/UltraScale等中大型项目(LUT > 80K、多时钟域、DDR/PCIe

weixin_34226182的博客 413

Java7/8 HashMap 底层结构分析 2021-07-23

HashMap 1、java8之前底层结构为:数组+链表. – 可以理解为当你new出一个HashMap时,首先会初始化一个指定长度的数组,数组的长度默认为16,数组的每一个元素都是一个单向链表,链表中每一个节点都包含四个属性:key的hash值、key、value、next指针.基于这种结构,想要定位一个entry,首先要根据key的hashcode与数组长度取模,模数即数组下标,这样可以定位到某一个数组元素,该动作时间复杂度为O(1),再遍历该元素下的链表,时间复杂度为O(n). 2、Java8后底层结

weixin_45861127的博客 514

Ubuntu 24.04中文输入法终极指南:从安装到疑难排解

本文是Ubuntu 24.04中文输入法的完整指南,详细介绍了如何通过图形界面或命令行安装和配置Intelligent Pinyin输入法。内容涵盖IBus框架的运作原理、输入法快捷键调校、模糊音设置,并重点解决了Qt应用无法输入中文的疑难问题,最后提供了Fcitx5备选方案及常见故障的排解方法。

weixin_29294975的博客 1246

Java8 HashMap底层原理

一、树集结构 1.1二叉查找树 二叉查找树(BST)具备什么特性呢? 1.左子树上所有结点的值均小于或等于它的根结点的值。 2.右子树上所有结点的值均大于或等于它的根结点的值。 3.左、右子树也分别为二叉排序树。 查找效率: 二叉查找树查找的最大次数为二叉查找树的最大高度 缺点: 可能造成线性结构 二叉查找树的相关原理可参考: 漫画算法:什么是红黑树?https://blog.youkuaiyun.com/p5deyt322jacs/article/details/78433942 1.2 红黑树 红黑树也是一

sinat_34814635的博客 1041

多目标跟踪中使用trackeval评估dancetrack运行结果

trackeval使用

qq_46144849的博客 1783

【win11+vs 2017+OpenCV4.5.5+Qt5.12配置】详细安装过程+小问题解决

由于Qt5无法与最新的vs2022兼容,扩展工具中一直显示不可用,所以将vs降级成vs2017。在安装Qt的过程中,会选择安装Qt套件,其中就的MCVS 2017,说明vs2017是与qt兼容的。当然也可以用qt creator这一原生IDE。OpenCV版本目前是最新的4.8.0,使用过程中没有什么问题,但是还是安装低版本大概率避免一些玄学问题。

qq_45306739的博客 3351

Java 8 Stream流底层原理

Java 8 Stream流底层原理

huang714的专栏 589

QT-使用ECharts显示地图,还有更多惊艳的图表等待你的使用

QT-使用ECharts显示地图前言一、使用步骤1.下载示例2. QT使用HTML文件配置3.使用HTML文件4. 数据交互及自适应总结注意:这个地图是百度的在线地图,需要百度API密钥和在联网的状态下使用。离线使用图表 前言 我上文QT图表chart-饼状图,使用qt自带的图表库charts来显示图表,实现数据可视化,但是QT自带的图表库显示效果并不佳,通俗说,就是不好看。 然而,有这么一个开源图表库,图表种类极多,并且效果良好,能够实现具有很好的视觉冲击的数据可视化。 它就是Apache ECharts

博咯的博客 4900

java for底层_Java8相关底层

Java8是往并行方向走的。由面向对象到函数式编程。在支持函数式编程的同时还可以支持面向对象的开发。在JDK1.8里面,接口里面可以有实现方法的!默认方法,default。实现这个接口。接口里面可以有静态方法注意Lambda表达式的类型势函数。但是在Java中,Lambda表达式是对象!他们必须依赖于一类特别的对象类型-函数式接口关于Function接口public classFunctionTe...

weixin_34409903的博客 174

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

《2022 元宇宙行业人才发展报告》出炉:C 语言、Java 等底层技术是硬通货,相关岗位平均月薪 1.8 万元

近日,智联招聘正式发布《2022 元宇宙行业人才发展报告》(以下简称“报告”),深度解析元宇宙领域职场现状。

programmerjob的博客 471

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

JAVA 基础学习笔记(8) String不可变的底层原理以及String的相关方法(上)

我本来以为我已经理解了String的不可变性,但没想到在写博客时发现我根本无法合理解释它的不可变性的原因,于是我又参考了韩顺平老师的Java教程中的解释才顺利写完。

罗不丢的博客 529

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

字符串相关类的底层原理

jdk8以前,是先创建一个StringBuilder对象,然后调用一个toString方法,再创建一个String对象,拼接这三个字符串需要创建四个对象。查看源码toString是new出来的,所以第二行至少有两个对象,一个是StringBuilder对象,一个是字符串对象1。jdk8及之后数组创建会进行预估,但是如果有多行多次拼接,那么则会浪费时间。

2401_83708850的博客 177

【JAVA】字符串相关类的底层原理

在所有的编程语言中,字符串是应用最广泛的一种数据类型,它是由一系列字符(如字母、数字、符号)组成的一种数据类型。在Java中,字符串一旦创建就不能修改,每次操作都会产生一个新的字符串。那么这些特性背后的内存原理是怎样的?这就是我今天要分享的主题:字符串在java内存中的底层原理。

2302_79323248的博客 1758

JAVA 字符串 12 字符串相关类的底层原理

如果没有变量参与,都是字符串直接相加,编译之后就是拼接之后的结果会复用串池中的字符串。如果有变量参与每一行拼接的代码,都会在内存中创建新的字符串,浪费内存。如果很多字符串变量拼接,不要直接+。在底层会创建多个对象,浪费时间,浪费性能。所有要拼接的内容都会往 StringBuilder 中放,不会创建很多无用的空间,节约内存默认创建一个长度为16的字节数组添加的内容长度小于16,直接存添加的内容大于16会扩容(原来的容量*2+2)如果扩容之后还不够,以后都会以实际长度为准。

qq_56808981的博客 839

JAVA 基础学习笔记(8) String不可变的底层原理以及String的相关方法(下)

在上篇里我只是提了提说用变量名去拼接字符串会创建新对象,但并没有解释原理,这里正好可以补充补充当我们需要频繁地对字符串进行修改时,使用 Java 的 StringBuilder 类可以提供更高效的处理方式。StringBuilder 是一个可变的字符串序列,它允许对字符串进行动态修改,而无需创建新的字符串对象。对之前的变量名拼接的代码进行调试。

罗不丢的博客 185

Java进阶:HashMap底层原理(通俗易懂篇)

在Java 7及之前的版本中,HashMap的底层数据结构主要是。:HashMap的核心是一个Entry数组(Entry<K,V>[] table),这个数组的大小总是2的幂。每个数组元素是一个单一的Entry节点,或者是一个链表的头节点。:当两个或更多的键经过哈希运算后映射到数组的同一个索引上时,就会形成链表。Entry节点包含了键值对以及指向下一个Entry的引用,以此来解决哈希冲突。

kfashfasf的博客 6517

Java8 Lambda

Lambda

Object的博客 149

Java7与Java8中的ConcurrentHashMap

JAVA7 Java7的ConcurrentHashMap里有多把锁,每一把锁用于其中一部分数据,那么当多线程访问容器里不同数据段的数据时,线程间就不会存在锁竞争,从而可以有效的提高并发访问效率呢。这就是“锁分离”技术。 ConcurrentHashMap是由Segment数组结构和HashEntry数组结构组成。Segment是一种可重入锁(继承了ReentrantLock),在Con...

weixin_30516243的博客 140

Java开发大厂面试第02讲:HahMap 的底层实现原理和JDK8的新特性优化

加载因子也叫扩容因子或负载因子,用来判断什么时候进行扩容的,假如加载因子是 0.5,HashMap 的初始化容量是 16,那么当 HashMap 中有 16*0.5=8 个元素时,HashMap 就会进行扩容。那加载因子为什么是 0.75 而不是 0.5 或者 1.0 呢?这其实是出于容量和性能之间平衡的结果:

2401_84585615的博客 772

Java HashMap・LinkedHashMap・TreeMap・HashTable底层原理解析

1、存储的是键值对,每一个键值对也叫做Entry。2、 key无序不重复, value没啥要求。3、不同的key可以取得相同的value。4、key若有相同的,原有的value覆盖而不是拒绝存入和set相反。

张紫娃的博客 361

HashSet以及哈希值和底层原理分析

遍历可以用迭代器和增强for。JDK7底层原理解析。

weixin_45755465的博客 132
上一篇: Java8新特性
下一篇: SQL规范
Art&Code
博客等级 码龄7年 77粉丝 554原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值