javaint=22是啥
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javaint=22是啥相关的知识,希望对你有一定的参考价值。
:ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized 方法(线程安全),通常性能上较ArrayList 差,而LinkedList 使用双向链表实现存储(将内存中零散的内存单元通过附加的引用关联起来,形成一个可以按序号索引的线性结构,这种链式存储方式与数组的连续存储方式相比,其实对内存的利用率更高),按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。Vector属于遗留容器(早期的JDK中使用的容器,除此之外Hashtable、Dictionary、BitSet、Stack、Properties都是遗留容器),现在已经不推荐使用,但是由于ArrayList和LinkedListed都是非线程安全的,如果需要多个线程操作同一个容器,那么可以通过工具类Collections中的synchronizedList方法将其转换成线程安全的容器后再使用(这其实是装潢模式最好的例子,将已有对象传入另一个类的构造器中创建新的对象来增加新功能)。补充:遗留容器中的Properties类和Stack类在设计上有严重的问题,Properties是一个键和值都是字符串的特殊的键值对映射,在设计上应该是关联一个Hashtable并将其两个泛型参数设置为String类型,但是Java API中的Properties直接继承了Hashtable,这很明显是对继承的滥用。这里复用代码的方式应该是HAS-A关系而不是IS-A关系,另一方面容器都属于工具类,继承工具类本身就是一个错误的做法,使用工具类最好的方式是HAS-A关系(关联)或USE-A关系(依赖) 。同理,Stack类继承Vector也是不正确的。
221.List、Map、Set 三个接口,存取元素时,各有什么特点?
答:List以特定索引来存取元素,可有重复元素。
Set不能存放重复元素(用对象的equals()方法来区分元素是否重复) 。Map保存键值对(key-value pair)映射,映射关系可以是一对一或多对一。Set和Map容器都有基于哈希存储和排序树(红黑树)的两种实现版本,基于哈希存储的版本理论存取时间复杂度为O(1),而基于排序树版本的实现在插入或删除元素时会按照元素或元素的键(key)构成排序树从而达到排序和去重的效果。
222.TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?
答:TreeSet要求存放的对象所属的类必须实现Comparable接口,该接口提供了比较元素的compareTo()方法,当插入元素时会回调该方法比较元素的大小。
TreeMap要求存放的键值对映射的键必须实现Comparable接口从而根据键对元素进行排序。
Collections工具类的sort方法有两种重载的形式,第一种要求传入的待排序容器中存放的对象比较实现Comparable接口以实现元素的比较;第二种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是Comparator接口的子类型 (需要重写compare方法实现元素的比较),相当于一个临时定义的排序规则,其实就是是通过接口注入比较元素大小的算法,也是对回调模式的应用。
225.说明类java.lang.ThreadLocal的作用和原理。列举在哪些程序中见过ThreadLocal的使用?
作用:
要编写一个多线程安全(Thread-safe)的程序是困难的,为了让线程共享资源,必须小心地对共享资源进行同步,同步带来一定的效能延迟,而另一方面,在处理同步的时候,又要注意对象的锁定与释放,避免产生死结,种种因素都使得编写多线程程序变得困难。
尝试从另一个角度来思考多线程共享资源的问题,既然共享资源这么困难,那么就干脆不要共享,何不为每个线程创造一个资源的复本。将每一个线程存取数据的行为加以隔离,实现的方法就是给予每个线程一个特定空间来保管该线程所独享的资源。
比如:在Hibernate中的Session就有使用。
ThreadLocal的原理
ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。
226.说说乐观锁与悲观锁
答:悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。
乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。
两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量。但如果经常产生冲突,上层应用会不断的进行retry,这样反倒是降低了性能,所以这种情况下用悲观锁就比较合适。
227.在Java中怎么实现多线程?描述线程状态的变化过程。
答:当多个线程访问同一个数据时,容易出现线程安全问题,需要某种方式来确保资源在某一时刻只被一个线程使用。需要让线程同步,保证数据安全线程同步的实现方案: 同步代码块和同步方法,均需要使用synchronized关键字
同步代码块:public void makeWithdrawal(int amt)
synchronized (acct)
同步方法:public synchronized void makeWithdrawal(int amt)
线程同步的好处:解决了线程安全问题
线程同步的缺点:性能下降,可能会带来死锁
229.在多线程编程里,wait方法的调用方式是怎样的?
答:wait方法是线程通信的方法之一,必须用在 synchronized方法或者synchronized代码块中,否则会抛出异常,这就涉及到一个“锁”的概念,而wait方法必须使用上锁的对象来调用,从而持有该对象的锁进入线程等待状态,直到使用该上锁的对象调用notify或者notifyAll方法来唤醒之前进入等待的线程,以释放持有的锁。
230.Java线程的几种状态
答:线程是一个动态执行的过程,它有一个从产生到死亡的过程,共五种状态:
新建(new Thread)
当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)
例如:Thread t1=new Thread();
就绪(runnable)
线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。例如:t1.start();
运行(running)
线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。
死亡(dead)
当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。
自然终止:正常运行run()方法后终止
异常终止:调用stop()方法让一个线程终止运行
堵塞(blocked)
由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。
正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。
正在等待:调用wait()方法。(调用motify()方法回到就绪状态)
被另一个线程所阻塞:调用suspend()方法。(调用resume()方法恢复)
232.volatile关键字是否能保证线程安全?
答:不能。虽然volatile提供了同步的机制,但是知识一种弱的同步机制,如需要强线程安全,还需要使用synchronized。
Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。
一、volatile的内存语义是:
当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量值立即刷新到主内存中。
当读一个volatile变量时,JMM会把该线程对应的本地内存设置为无效,直接从主内存中读取共享变量。
二、volatile底层的实现机制
如果把加入volatile关键字的代码和未加入volatile关键字的代码都生成汇编代码,会发现加入volatile关键字的代码会多出一个lock前缀指令。
1 、重排序时不能把后面的指令重排序到内存屏障之前的位置
2、使得本CPU的Cache写入内存
3、写入动作也会引起别的CPU或者别的内核无效化其Cache,相当于让新写入的值对别的线程可见。
238.同步和异步有何异同,在什么情况下分别使用它们?
答:1.如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
2.当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。
3.举个例子: 打电话是同步 发消息是异步
239.Java线程中,sleep()和wait()区别
答:sleep是线程类(Thread)的方法;作用是导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复;调用sleep()不会释放对象锁。
wait是Object类的方法;对此对象调用wait方法导致本线程放弃对象锁,进入等 待此对象的等待锁定池。只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池,准备获得对象锁进行运行状态。
发布于 3 年前著作权归作者所有 参考技术A jabaint是采用补码表示。由于我们经常在做题中会遇到Java的位运算,Java的位运算只能用于int和long型。jabaint=22
Java int[] 数组到 HashSet<Integer>
【中文标题】Java int[] 数组到 HashSet<Integer>【英文标题】:Java int[] array to HashSet<Integer> 【发布时间】:2012-08-15 08:52:59 【问题描述】:我有一个 int 数组:
int[] a = 1, 2, 3;
我需要一个类型的集合:
Set<Integer> s;
如果我执行以下操作:
s = new HashSet(Arrays.asList(a));
当然,它认为我的意思是:
List<int[]>
而我的意思是:
List<Integer>
这是因为 int 是一个原语。如果我使用了字符串,一切都会起作用:
Set<String> s = new HashSet<String>(
Arrays.asList(new String[] "1", "2", "3" ));
如何轻松、正确、简洁地从:
A) int[] a...
到
B) Integer[] a ...
谢谢!
【问题讨论】:
可能重复:***.com/questions/1073919/… 【参考方案1】:使用流:
// int[] nums = 1,2,3,4,5
Set<Integer> set = Arrays.stream(nums).boxed().collect(Collectors.toSet())
【讨论】:
【参考方案2】:该问题提出了两个独立的问题:将int[]
转换为Integer[]
并从int[]
创建一个HashSet<Integer>
。两者都可以通过 Java 8 流轻松实现:
int[] array = ...
Integer[] boxedArray = IntStream.of(array).boxed().toArray(Integer[]::new);
Set<Integer> set = IntStream.of(array).boxed().collect(Collectors.toSet());
//or if you need a HashSet specifically
HashSet<Integer> hashset = IntStream.of(array).boxed()
.collect(Collectors.toCollection(HashSet::new));
【讨论】:
我认为值得一提的是这种线技术较慢。我使用IntStream.of(nums).boxed().collect(Collectors.toSet())
而不是只循环元素,这将我的运行时间平均从 18 毫秒增加到 25 毫秒。【参考方案3】:
一些进一步的解释。 asList 方法有这个签名
public static <T> List<T> asList(T... a)
如果你这样做:
List<Integer> list = Arrays.asList(1, 2, 3, 4)
或者这个:
List<Integer> list = Arrays.asList(new Integer[] 1, 2, 3, 4 )
在这些情况下,我相信 java 能够推断出您想要返回一个 List,因此它会填充类型参数,这意味着它需要 Integer 参数来调用方法。因为它能够将值从 int 自动装箱到 Integer,所以很好。
但是,这行不通
List<Integer> list = Arrays.asList(new int[] 1, 2, 3, 4 )
因为包装强制的原语(即 int[] 到 Integer[])没有内置到语言中(不知道他们为什么不这样做,但他们没有这样做)。
因此,每个原始类型都必须作为它自己的重载方法来处理,这就是 commons 包所做的。即。
public static List<Integer> asList(int i...);
【讨论】:
相信你也可以拨打Arrays.<Integer>asList(1, 2, 3, 4)
问题的标题是Java int[] array to HashSet<Integer>
,而您的答案中没有HashSet
。【参考方案4】:
或者您可以轻松使用Guava 将int[]
转换为List<Integer>
:
Ints.asList(int...)
asList
public static List<Integer> asList(int... backingArray)
返回一个由指定数组支持的固定大小的列表,类似于
Arrays.asList(Object[])
。该列表支持List.set(int, Object)
,但任何将值设置为null
的尝试都将导致NullPointerException
。返回的列表维护写入或读取的
Integer
对象的值,但不维护身份。例如,未指定返回列表的list.get(0) == list.get(0)
是否为真。
【讨论】:
【参考方案5】:你可以在Apache Commons中使用ArrayUtils:
int[] intArray = 1, 2, 3 ;
Integer[] integerArray = ArrayUtils.toObject(intArray);
【讨论】:
如果 Commons 有方法可以做到这一点,这意味着没有办法使用基本 JDK 来做到这一点......感谢您的指点! Commons 库在 Android 上占用了大量的方法引用,强烈建议避免使用。这很有意义,并且适用于普通 Java。【参考方案6】:另一种选择是使用来自Eclipse Collections 的原始集。您可以轻松地将int[]
转换为MutableIntSet
再转换为Set<Integer>
或Integer[]
,如下所示,或者您可以按原样使用MutableIntSet
,这将提高内存效率和性能。
int[] a = 1, 2, 3;
MutableIntSet intSet = IntSets.mutable.with(a);
Set<Integer> integerSet = intSet.collect(i -> i); // auto-boxing
Integer[] integerArray = integerSet.toArray(new Integer[]);
如果您想直接从 int 数组转到 Integer 数组并保持顺序,那么这将起作用。
Integer[] integers =
IntLists.mutable.with(a).collect(i -> i).toArray(new Integer[]);
注意:我是 Eclipse Collections 的提交者
【讨论】:
【参考方案7】:使用下面的 sn-p 将数组中的元素添加到 Set 中
public class RemoveDuplicateElements
public static void main(String args[])
int array[] = 0,1,2,3,4,5,6,7,8,9,1,2,3,4,5;
Set <Integer> abc = new HashSet <Integer>();
for (Integer t:array)
abc.add(t);
System.out.println("sampleSet"+abc);
【讨论】:
OP正在询问JAVA8方式。以上是关于javaint=22是啥的主要内容,如果未能解决你的问题,请参考以下文章
javaint类型占用几个字节,成功收获美团,小米offer