我最近创建了一个简单的方法,它将HashMap和LinkedList作为参数。它遍历HashMap,找到遵循这些规则的任何两个条目:
遵循这些规则的对将添加到LinkedList。它看起来像这样:
private static void compare2(HashMap<Integer,String> values,List<String>results){
if (values.size()>1) {
for(HashMap.Entry<Integer,String> entry1:values.entrySet()){
for (HashMap.Entry<Integer,String> entry2:values.entrySet()){
if (entry1.getValue().equals(entry2.getValue()))continue;
if ((entry1.getKey() + entry2.getKey())%100 == 0 && (entry1.getKey() + entry2.getKey())<1000){
results.add(entry1.getKey() + "+" + entry2.getKey() + "=" + entry1.getKey() + entry2.getKey());
results.add(entry1.getValue());
results.add(entry2.getValue());
}
}
}
}
}
现在我想创建类似的方法,找到遵循相同规则的3个条目。问题是我想重用现有的代码而不是复制/粘贴这个和modyfiyng,我似乎无法找到一种方法来做到这一点。如果我需要改变我的方法,我不介意,只要结果是相同的。
答案 0 :(得分:1)
您可以将数字量设为参数:N。
您可以继续使用for循环,但另一种示例方法可能是使用lambda&stream和stream重构您的方法,如下所示:
List<List<Map.Entry<Integer, String>>> compareN(HashMap<Integer, String> map, int n) {
return map.entrySet().stream()
.map(entry -> listOfNAccompanyingEntriesThatSatisfyTheConditions(entry, emptyList(), map, n - 1))
.filter(list -> !list.isEmpty())
.collect(toList());
}
方法listOfNAccompanyingEntriesThatSatisfyTheConditions
是递归方法:
private List<Map.Entry<Integer, String>>
listOfNAccompanyingEntriesThatSatisfyTheConditions(Map.Entry<Integer, String> newEntry,
List<Map.Entry<Integer, String>> selectedEntries,
HashMap<Integer, String> originalMap,
int n) {
List<Map.Entry<Integer, String>> newSelectedEntries = join(newEntry, selectedEntries);
if (n == 0) return satisifiesCondition(newSelectedEntries) ? selectedEntries : emptyList();
return originalMap.entrySet().stream()
.filter(entry -> !selectedEntries.contains(entry) && !entry.equals(newEntry))
.map(entry -> listOfNAccompanyingEntriesThatSatisfyTheConditions(entry, newSelectedEntries, originalMap, n - 1))
.flatMap(Collection::stream)
.collect(toList());
}
对于每个 n ,该方法会在原始完整列表中再次拍摄,以累积可能满足要求的子列表。如果达到了数量(n == 0),则递归停止并验证停止条件:
private static boolean satisifiesCondition(List<Map.Entry<Integer, String>> entries) {
int sum = sumOfTheKeysFrom(entries);
return sum % 100 == 0 && sum < 1000;
}
但是,这种方法实际上是对您的实现的精确翻译,并且仍然存在同样的问题。例如,如果您为
运行它HashMap<Integer, String> map = new HashMap<Integer, String>() {{
put(1, "fred");
put(2, "anja");
put(24, "tom");
put(45, "eddy");
put(22, "lenny");
put(77, "tommy");
put(55, "henry");
put(43, "alfred");
}};
您将使用相同的条目两次产生双重结果和结果,例如:
[1 = fred,22 = lenny,1 = fred,77 = tommy] [2 = anja,55 = henry,2 = anja, 43 =阿尔弗雷德]
然而,通过一些小的调整可以很容易地解决这些问题。
如果您不熟悉流,lambda或递归,我建议您使用命令式方法实现相同的功能。还要注意我在示例代码中并不关心性能,因为我认为这个问题是一种练习。
答案 1 :(得分:-1)
尝试这样的事情:
@SafeVarargs
private static void check( final List<String> results,
final Map.Entry<Integer, String>... vals )
{
int sum = 0;
for ( final Map.Entry<Integer, String> val : vals )
{
final Integer key = val.getKey();
sum += null == key ? 0 : key;
}
if ( sum < 1000 && 0 == ( sum % 100 ) )
{
final StringBuilder result = new StringBuilder( 200 );
for ( final Map.Entry<Integer, String> val : vals )
{
result.append( " + " ).append( val.getKey() );
}
results.add( result.append( " = " ).append( sum ).substring( 3 ) );
for ( final Map.Entry<Integer, String> val : vals )
{
results.add( val.getValue() );
}
}
}
private static void compare2( final HashMap<Integer, String> values,
final List<String> results )
{
if ( values.size() > 1 )
{
for ( final HashMap.Entry<Integer, String> entry1 : values.entrySet() )
{
for ( final HashMap.Entry<Integer, String> entry2 : values.entrySet() )
{
if ( entry1 == entry2 )
continue;
check( results, entry1, entry2 );
}
}
}
}
private static void compare3( final HashMap<Integer, String> values,
final List<String> results )
{
if ( values.size() > 2 )
{
for ( final HashMap.Entry<Integer, String> entry1 : values.entrySet() )
{
for ( final HashMap.Entry<Integer, String> entry2 : values.entrySet() )
{
for ( final HashMap.Entry<Integer, String> entry3 : values.entrySet() )
{
if ( entry1 == entry2 || entry1 == entry3 || entry2 == entry3 )
continue;
check( results, entry1, entry2, entry3 );
}
}
}
}
}