Map: 映射, 是双列集合顶层接口
java.util.Map<k,v>
k: key 键 唯一
v: value 值 可重复
public V put(K key,V Value)
// 指定的键与指定值添加到Map集合中, 添加成功返回null, 添加失败返回之前的值
public V putIfAbsent(K key,V Value)
// jdk1.8后新增 键相同值不覆盖返回原来的值
public V get(Object key)
// 根据指定的键, 获取对应值, 不存在返回null
public V getOrDefault(Object key, V defaultValue)
// jdk1.8后新增 不存在返回defaultValue
public boolean containsKey(Object key)
// 判断集合中是否包含指定的键
public V remove(Object key)
// 根据指定的键, 删除一对元素, 返回被删除的值
public V remove(Object key, Object value)
// 根据指定的键和值, 都一致则删除, 返回被删除的值
Set<K> keySet()
// 获取存放所有键的Set集合
Collection<V> values()
// 获取存放所有值的集合
Set<Map.Entry<K, V>> entrySet()
// 获取键值对映射关系对象的Set集合
interface Entry<K,V>
K getKey()
// 获取映射关系对象中的键
V getValue()
// 获取映射关系对象中的值
底层数据结构: 链表 + 哈希表
链表保证元素有序 哈希表保证元素唯一
public class Demo {
public static void main(String[] args) {
Map<String, Integer> map = new LinkedHashMap<>();
map.put("1张三",14);
map.put("2李四",17);
// put
// 添加成功返回 null
System.out.println(map.put("3王五", null));
// 添加失败返回之前的值, 并用新值覆盖
System.out.println(map.put("2李四", 19));
// putIfAbsent
// 键不存在添加新的键值对, 添加成功返回null
System.out.println(map.putIfAbsent("4刘六", 19));
// 若键存在 原有值不改变 并返回原有值
System.out.println(map.putIfAbsent("1张三", 11));
// get
// 根据键找值, 存在则返回键对应的值
System.out.println(map.get("1张三"));
// 不存在则返回null
System.out.println(map.get("2"));
// getOrDefault
// 键存在 返回对应值
System.out.println(map.getOrDefault("1张三", -1));
// 若不存在 则返回defaultValue
System.out.println(map.getOrDefault("2", -1));
// 判断集合中是否包含指定的键, 存在返回true, 不存在返回false
System.out.println(map.containsKey("2李四"));
// 根据键删除一对元素 返回被删除的值
// 不存在则返回null
System.out.println(map.remove("1"));
System.out.println(map.remove("1张三"));
System.out.println(map);
// 遍历
// 方式1
// 获取存放所有键的集合
Set<String> set = map.keySet();
// 获取存放所有值的集合
Collection<Integer> values = map.values();
// 迭代器
Iterator<Integer> iterator = values.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println();
// 增强for
for (Integer value : values) {
System.out.print(value + " ");
}
System.out.println();
// 迭代器
Iterator<String> it = set.iterator();
while (it.hasNext()) {
String key = it.next();
System.out.print(key + " = " + map.get(key) + "\t");
}
System.out.println();
// 增强for
for (String s : set) {
System.out.print(s + " = " + map.get(s) + "\t");
}
System.out.println();
// 方式2
// Entry是Map的内部类 所以调用时需要Map.Entry
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
// 迭代器
Iterator< Map.Entry<String, Integer>> entries = entrySet.iterator();
while (entries.hasNext()) {
Map.Entry<String, Integer> next = entries.next();
System.out.print(next.getKey() + " = " + next.getValue() + "\t");
}
System.out.println();
// 增强for
for (Map.Entry<String, Integer> entry : entrySet) {
System.out.print(entry.getKey() + " = "+entry.getValue() + "\t");
}
}
}
java.util.TreeMap
底层数据结构是红黑树 键 排序 具有唯一性 不允许null键 允许null值
/*
java.util.TreeMap
底层数据结构是红黑树 键 排序 具有唯一性 不允许null键 允许null值
构造方法:
public TreeMap() 空参构建, 集合中的键必须实现自然排序接口 Comparable 的方法 CompareTo
public TreeMap(Comparator<? super K> comparator) 需传入比较器对象
*/
public class Demo {
public static void main(String[] args) {
TreeMap<Person, String> map = new TreeMap<>();
map.put(new Person("张三",12),"bj");
map.put(new Person("张三",14),"sh");
map.put(new Person("李四",15),null);
map.put(new Person("王五",11),"gz");
map.put(new Person("宫本",19),"jp");
// 不允许null键
// map.put(null,"us");
System.out.println(map);
// 获取第一个键
System.out.println(map.firstKey());
// 获取最后一个键
System.out.println(map.lastKey());
// 获取第一个键值对
System.out.println(map.firstEntry());
// 获取最后一个键值对
System.out.println(map.lastEntry());
// 获取 按排序方法 取索引 >= 指定键的最小键(>=指定键并距离最近)
System.out.println(map.ceilingKey(new Person("李四", 13)));
// 获取 按排序方法 取索引 >= 指定键的最小键值对(>=指定键并距离最近)
System.out.println(map.ceilingEntry(new Person("李四", 13)));
// 获取 按排序方法 取索引 <= 指定键的最小键(<=指定键并距离最近)
System.out.println(map.floorKey(new Person("李四", 13)));
// 获取 按排序方法 取索引 <= 指定键的最小键值对(<=指定键并距离最近)
System.out.println(map.floorEntry(new Person("李四", 13)));
System.out.println("=================");
TreeMap<Person, String> treeMap = new TreeMap<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
if (o1.age == o2.age) {
return o2.name.compareTo(o1.name);
}
return o1.age - o2.age;
}
});
treeMap.put(new Person("张三",12),"bj");
treeMap.put(new Person("张三",14),"sh");
treeMap.put(new Person("李四",15),null);
treeMap.put(new Person("王五",11),"gz");
treeMap.put(new Person("宫本",19),"jp");
System.out.println(treeMap);
}
}
class Person implements Comparable<Person> {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person o) {
if (o.age == this.age) {
return o.name.compareTo(this.name);
}
return o.age - this.age;
}
@Override
public String toString() {
return "{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
/*
java.util.HashMap
底层数据结构是哈希表 允许null键和null值 键是无序的 具有唯一性
先比较hashCode
不同 元素不相同
相同 继续比较equals
相同
不同
因此必须重写hashCode和equals方法
*/
public class Demo {
public static void main(String[] args) {
Map<Person, String> map = new HashMap<Person, String>();
map.put(new Person("张三",12),"bj");
map.put(new Person("李四",12),"sh");
map.put(new Person("王五",12),"gz");
map.put(new Person("宫本",12),"jp");
map.put(null,"us");
Set<Person> peopleSet = map.keySet();
for (Person person : peopleSet) {
if (person == null) {
System.out.println(person + " " + map.get(person));
continue;
}
System.out.println(person.getName() + " " + person.getAge() + " " + map.get(person));
}
Set<Map.Entry<Person, String>> entries = map.entrySet();
for (Map.Entry<Person, String> entry : entries) {
Person key = entry.getKey();
if (key == null) {
System.out.println(key + " " + entry.getValue());
continue;
}
System.out.println(key.getName() + " "+ key.getAge() + " "+entry.getValue());
}
}
}
class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (age != person.age) return false;
return name != null ? name.equals(person.name) : person.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
}
在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化.
// 格式
修饰符 返回值类型 方法名(参数类型... 形参名){ }
/*
可变参数 指参数的个数可变
当参数数据类型确定,且需要较多次重载时, 可以使用可变参数
可变参数必须放在参数列表的最后, 且只能有一个可变参数
格式: 本质上就是数组
public static int avg(int... nums)
当不传入参数时, 相当于传了空数组
由于本质是数组, 因此传入数组也可以
*/
public class function {
public static void main(String[] args) {
System.out.println(avg(1,2,3,4,5,7,8,9,2));
System.out.println(avg(18,9,2));
System.out.println(avg(1,2));
int[] arr = {1,23,42,45,34,21};
System.out.println(avg(arr));
}
public static int avg(int... nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i];
}
return sum / nums.length;
}
}
使用54张牌打乱顺序,三个玩家参与游戏,三人交替摸牌,每人17张牌,最后三张留作底牌.
import java.util.*;
public class PokerDemo {
public static void main(String[] args) {
Map<Integer, String> pokerMap = new HashMap<Integer, String>();
ArrayList<Integer> pokerIndex = new ArrayList<Integer>();
String[] colors = {"♥","♠","♣","♦"};
String[] numbers = "2-A-K-Q-J-10-9-8-7-6-5-4-3".split("-");
int index = 2;
pokerMap.put(0, "大王");
pokerMap.put(1, "小王");
for (String number : numbers) {
for (String color : colors) {
pokerMap.put(index, color+number);
index++;
}
}
for (int i = 0; i < 54; i++) {
pokerIndex.add(i);
}
Collections.shuffle(pokerIndex);
ArrayList<Integer> player1 = new ArrayList<Integer>();
ArrayList<Integer> player2 = new ArrayList<Integer>();
ArrayList<Integer> player3 = new ArrayList<Integer>();
ArrayList<Integer> dipai = new ArrayList<Integer>();
for (int i = 0; i < pokerIndex.size(); i++) {
if (i >= 51){
dipai.add(pokerIndex.get(i));
} else if (i % 3 == 0) {
player1.add(pokerIndex.get(i));
} else if (i % 3 == 1) {
player2.add(pokerIndex.get(i));
} else {
player3.add(pokerIndex.get(i));
}
}
System.out.println("玩家1: " + showPoker(player1, pokerMap));
System.out.println("玩家2: " + showPoker(player2, pokerMap));
System.out.println("玩家3: " + showPoker(player3, pokerMap));
System.out.println("底牌: " + showPoker(dipai, pokerMap));
}
public static String showPoker(ArrayList<Integer> player, Map<Integer, String> pokerMap) {
Collections.sort(player);
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < player.size(); i++) {
sb.append(pokerMap.get(player.get(i)));
if (i == player.size() - 1) {
sb.append("]");
} else {
sb.append(", ");
}
}
return sb.toString();
}
}
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option
我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一