Categories
discuss

Unable to understand this Java Stream+Generics example

Could someone help me to understand why this code behaves as described in the comments

// 1) compiles
List<Integer> l = Stream.of(1, 2, 3).collect(ArrayList::new, ArrayList::add, ArrayList<Integer>::addAll);

/*
 *  2) does not compile
 *  
 *  Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
 *      Type mismatch: cannot convert from Object to <unknown>
 *      The type ArrayList does not define add(Object, Integer) that is applicable here
 *      The type ArrayList does not define addAll(Object, Object) that is applicable here
 */
Stream.of(1, 2, 3).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);

// 3) compiles
Stream.of(1, 2, 3).collect(ArrayList<Integer>::new, ArrayList::add, ArrayList::addAll);

/*
 *  4) does not compile
 *  
 *  Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
 *      Type mismatch: cannot convert from Object to <unknown>
 *      The type ArrayList does not define add(Object, Integer) that is applicable here
 *      The type ArrayList<Integer> does not define addAll(Object, Object) that is applicable here
 */
Stream.of(1, 2, 3).collect(ArrayList::new, ArrayList::add, ArrayList<Integer>::addAll);  

It has clearly something to do with the definition of a type in generic methods, it’s an information that must be somehow provided… but why is it mandatory? Where and how, syntactically, should I have figured it out from the signature of methods of() and collect()?

public static<T> Stream<T> of(T... values) {...}

<R> R collect(Supplier<R> supplier,
              BiConsumer<R, ? super T> accumulator,
              BiConsumer<R, R> combiner);

Answer

Although this is not an answer which analyzes the Lambda spec on http://download.oracle.com/otndocs/jcp/lambda-0_9_3-fr-eval-spec/index.html, I nevertheless tried to find out on what it depends.

Copying two methods from the Stream class:

static class Stream2<T> {

    @SafeVarargs
    @SuppressWarnings("varargs") // Creating a stream from an array is safe
    public static<T> Stream2<T> of(T... values) {
        return new Stream2<>();
    }

     public  <R> R collect(  Supplier<R> supplier,
             BiConsumer<R, ? super T> accumulator,
             BiConsumer<R, R> combiner){return null;}

}

This compiles:

Stream2.of(1,2,3).collect(ArrayList::new, ArrayList::add, ArrayList::addAll );

like OP’s (2).

Now changing the collect method to by moving the first argument to the third place

     public  <R> R collect(BiConsumer<R, ? super T> accumulator,
             BiConsumer<R, R> combiner,
             Supplier<R> supplier
     ){return null;}

This still works (5):

 Stream2.of(1,2,3).collect(ArrayList::add, ArrayList::addAll,ArrayList::new );

Also this works (6):

 Stream2.of(1,2,3).collect(ArrayList::add, ArrayList::addAll,ArrayList<Integer>::new );

These don’t work (7,8):

 Stream2.of(1,2,3).collect(ArrayList<Integer>::add, ArrayList::addAll,ArrayList::new );
 Stream2.of(1,2,3).collect(ArrayList<Integer>::add, ArrayList<Integer>::addAll,ArrayList::new );

But this works again (9):

 Stream2.of(1,2,3).collect(ArrayList<Integer>::add, ArrayList<Integer>::addAll,ArrayList<Integer>::new );

So i guess when a supplier is annotated with the explicit type argument, it seems to work. When only the consumers are, it does not. But maybe someone else knows why this makes a difference.

EDIT: Trying to use a TestList, it gets even stranger:

public class StreamTest2 {

    public static void main(String[] args) {

        Stream.of(1, 2, 3).collect(TestList::new, TestList::add, TestList<Integer>::addAll);
        Stream.of(1, 2, 3).collect(TestList::new, TestList::add, TestList<Integer>::addAll2);
        Stream.of(1, 2, 3).collect(TestList::new, TestList::add, TestList<Integer>::addAll3);
        Stream.of(1, 2, 3).collect(TestList::new, TestList::add, TestList<Integer>::addAll4);
        Stream.of(1, 2, 3).collect(TestList::new, TestList::add, TestList<Integer>::addAll5);
        Stream.of(1, 2, 3).collect(TestList::new, TestList::add, TestList<Integer>::addAll6);

    }
}

class TestList<T> extends AbstractList<T> {

    @Override
    public T get(int index) {
        return null;
    }

    @Override
    public int size() {
        return 0;
    }

    @Override
    public boolean addAll(Collection<? extends T> c) {
        return true;
    }

    public boolean addAll2(TestList<? extends T> c) {
        return true;
    }
    public boolean addAll3(Collection<T> c) {
        return true;
    }

    public boolean addAll4(List<? extends T> c) {
        return true;
    }
    public boolean addAll5(AbstractList<? extends T> c) {
        return true;
    }

    public boolean addAll6(Collection<? extends T> c) {
        return true;
    }

    @Override
    public boolean add(T e) {
        return true;
    }
}

addAll does not work, but addAll26 do work. Even addAll6 works, which has the same signature as the original addAll.

Categories
discuss

Iterate through HTML DOM and get depth

How is it possible to iterate through the HTML DOM and list all nodes with there depth in javascript.

Example:

<div>
    <img src="foo.jpg">
    <p>
        <span>bar</span>
    </p>
</div>

would result in

  • div 0
  • img 1
  • p 1
  • span 2

Answer

Write a recursive function which tracks the depth:

function element_list(el,depth) {
    console.log(el+' '+depth);
    for(var i=0; i<el.children.length; i++) {
        element_list(el.children[i],depth+1);
    }
}
element_list(document,0);

As CodeiSir points out, this will also list text nodes, but we can filter them out by testing the nodeType. Variations on this code will allow/ignore other node types as desired.

function element_list(el,depth) {
   if (el.nodeType === 3) return;
Categories
discuss

Android Studio 2.0: Why does Instant Run not work when modifying xml layout resources?

This is a very new feature, as Android Studio 2.0 is only available in the canary release channel, however I was hoping someone could further explain how the Instant Run feature works.

If I modify code within my Java classes (Activities, Fragments, etc.) then Instant Run works smoothly. It keeps the instance of the app running and swaps out code behind the scenes, greatly improving the time it takes for me to test (which is awesome, btw).

However, if I modify existing layout xml resources, then it has to recompile a build and deploy it. So my questions are:

  1. Why does it need to rebuild when modifying existing layout xml resources?
  2. Are there plans for the future to allow hot-swapping XML resources so that I don’t have to rebuild every time I want to see a change in layout? (Although, I know I can just view changes in the Design view).

Question #1 is more important to me at the moment, because I’d like to understand how it all works.
Also, congratulations to the Android Studio team. The IDE has come a long way. The performance improvements are life-changing.

Answer

enter image description here

As you know all the resources used in your xml file are converted into static fields in R class. As per the information got from http://tools.android.com/tech-docs/instant-run changing static fields are not supported by instant Run.

Categories
discuss

Unable to schedule notification with AlarmManager on Android (using Qt)

I am doing the following from a qt 5.5. project.

I am trying to schedule a local notification using the alarm manger in android. This is the code to schedule the notification:

class ScheduledNotifications {
    static public int notification_id = 0;
    static int scheduleNotification(String title, String content, int futureInMilliseconds) {
        ++notification_id;

        Intent notificationIntent = new Intent(QtNative.activity(),  NotificationPublisher.class);
        notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID, notification_id);
        notificationIntent.putExtra(NotificationPublisher.NOTIFICATION, createNotification(title,content));
        PendingIntent pendingIntent = PendingIntent.getBroadcast(QtNative.activity(), 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        AlarmManager alarmManager = (AlarmManager)QtNative.activity().getSystemService(Context.ALARM_SERVICE);
        alarmManager.set(AlarmManager.RTC_WAKEUP, /*futureInMilliseconds*/0, pendingIntent);

        Log.d("!" ,"Scheduled");
        return notification_id;
    }

    static public Notification createNotification(String title, String content) {
            Notification.Builder builder = new Notification.Builder(QtNative.activity());


            builder.setContentTitle(title);
            builder.setContentText(content);
            return builder.build();
    }
}

And this is the NotificationPublisher, which should display the notification:

class NotificationPublisher extends BroadcastReceiver {

    public static String NOTIFICATION_ID = "notification-id";
    public static String NOTIFICATION = "notification";

    public void onReceive(Context context, Intent intent) {//Called when its time to show the notification ...

        Log.d("!", "Notified");
        NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);

        Notification notification = intent.getParcelableExtra(NOTIFICATION);
        int id = intent.getIntExtra(NOTIFICATION_ID, 0);
        notificationManager.notify(id, notification);

    }
}

For debug puproses I set the “wakeup” time to 0 (so the notification should appear immediately).

The Lod.d("!","Scheduled") output appears in the console output, but the Log.d("!", "Notified") does not. So am I scheduling the alarm somehow incorrect?

Answer

I had an error in the AndroidManifest.xml. The NotificationPublisher needs to be registered as a receiver, like this:

<receiver android:name="de.goodpoint_heidelberg.NotificationPublisher" android:enabled="true"/>
Categories
discuss

JavaScript Regex: Finding a String that does not contain

I’m trying to write a regex that will find a string of HTML tags inside a code editor (Khan Live Editor) and give the following error:

"You can't put <h1.. 2.. 3..> inside <p> elements."

This is the string I’m trying to match:

<p> ... <h1>

This the string I don’t want to match:

<p> ... </p><h1>

Instead the expected behavior is that another error message appears in this situation.

So in English I want a string that;
– starts with <p> and
– ends with <h1> but
– does not contain </p>.

It’s easy enough to make this work if I don’t care about the existence of a </p>. My expression looks like this, /<p>.*<h[1-6]>/ and it works fine. But I need to make sure that </p> does not come between the <p> and <h1> tags (or any <h#> tag, hence the <h[1-6]>).


I’ve tried a lot of different expressions from some other posts on here:

Regular expression to match a line that doesn’t contain a word?

From which I tried: <p>^((?!</p>).)*$</h1>

regex string does not contain substring

From which I tried: /^<p>(?!</p>)<h1>$/

Regular expression that doesn’t contain certain string

This link suggested: aa([^a] | a[^a])aa

Which doesn’t work in my case because I need the specific string “</p>” not just the characters of it since there might be other tags between <p> ... <h1>.


I’m really stumped here. The regex I’ve tried seems like it should work… Any idea how I would make this work? Maybe I’m implementing the suggestions from other posts wrong?

Thanks in advance for any help.

Edit:

To answer why I need this done:

The problem is that <p><h1></h1></p> is a syntax error since h1 closes the first <p> and there is an unmatched </p>. The original syntax error is not informative, but in most cases it is correct; my example being the exception. I’m trying to pass the syntax parser a new message to override the original message if the regex finds this exception.

Answer

Your first regular expression was close, but needed to remove the ^ and $ characters. If you need to match across newlines, you should use [/s/S] instead of ..

Here’s the final regex: <p>(?:(?!</p>)[sS])*<h[1-6]>

However, having a header tag (<h1><h6>) is perfectly legal inside a paragraph element. They’re just considered sibling elements, with the paragraph element ending where the header element begins.

A p element’s end tag may be omitted if the p element is immediately followed by an address, article, aside, blockquote, dir, div, dl, fieldset, footer, form, h1, h2, h3, h4, h5, h6, header, hr, menu, nav, ol, p, pre, section, table, or ul element, or if there is no more content in the parent element and the parent element is not an a element.

http://www.w3.org/TR/html-markup/p.html

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..